Create feeds
Deploy issuer-signed scalar feeds via the factory, create aggregator adapters for stable consumer addresses, and register external feeds in the directory.
This guide covers three ways to add feeds to the FeedsDirectory: deploying new issuer-signed feeds, creating aggregator adapters, and registering external feed contracts.
Create an issuer-signed scalar feed
Issuer-signed feeds are deployed via the IssuerSignedScalarFeedFactory addon. Updates are authorized through EIP-712 typed data signatures from trusted issuers.
Prerequisites
Verify the factory is installed:
curl "$DALP_API_URL/system/feeds/capabilities" \
-H "X-Api-Key: $API_KEY"Check that issuerSignedScalarFeedFactory.installed is true in the response.
Register a topic
Before creating a feed, register the topic name in the TopicSchemeRegistry. The API accepts either a human-readable topicName string, a topicId hash, or both. When topicName is provided, the on-chain topicId is computed internally. When both are provided, the API verifies they match.
Deploy the feed
curl -X POST "$DALP_API_URL/system/feeds/issuer-signed/create" \
-H "X-Api-Key: $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"subject": "0xTokenAddress",
"topicName": "PRICE/USD",
"decimals": 8,
"description": "USD price feed for token",
"historyMode": "BOUNDED",
"historySize": 100,
"requirePositive": true,
"driftAllowance": 0
}'You can also use topicId instead of topicName:
curl -X POST "$DALP_API_URL/system/feeds/issuer-signed/create" \
-H "X-Api-Key: $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"subject": "0xTokenAddress",
"topicId": "109530253152918849413157129862927938307097811649912148858507112538040816216783",
"decimals": 8,
"description": "USD price feed for token",
"historyMode": "BOUNDED",
"historySize": 100,
"requirePositive": true,
"driftAllowance": 0
}'Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
subject | address | Yes | The asset or entity this feed relates to |
topicName | string | At least one of topicName or topicId | Human-readable topic name (e.g., "PRICE/USD"). Must be registered in the TopicSchemeRegistry first. |
topicId | string | At least one of topicName or topicId | The keccak256 hash of the topic name, as a decimal string |
decimals | number | Yes | Decimal precision for feed values (0--18) |
description | string | Yes | Human-readable description of the feed |
historyMode | enum | Yes | LATEST_ONLY, BOUNDED, or FULL |
historySize | number | Yes | Ring buffer size when using BOUNDED mode (ignored for other modes) |
requirePositive | boolean | Yes | Reject updates with non-positive values |
driftAllowance | number | Yes | Maximum allowed drift in seconds between observedAt and block timestamp |
walletVerification | object | No (optional for API key auth) | Wallet verification for transaction signing — required for session-based auth only |
Response (synchronous, default):
{
"data": {
"feedAddress": "0x...",
"subject": "0x...",
"topicId": "0x...",
"decimals": 8,
"historyMode": "BOUNDED",
"transactionHash": "0x..."
},
"meta": { "txHashes": ["0x..."] },
"links": { "self": "/system/feeds/issuer-signed/create" }
}To request asynchronous processing, add Prefer: respond-async to the request headers. The server returns HTTP 202 with a status URL for polling:
{
"transactionId": "01965a1b-...",
"status": "pending",
"statusUrl": "/transactions/01965a1b-..."
}Poll the statusUrl until status changes to "completed" or "failed".
The feed is automatically registered in the FeedsDirectory upon creation.
Permissions
Feed creation supports two authorization paths:
- Feeds Manager role (system-level) — can create feeds for any subject including global (address(0)).
- Governance role on subject token — holders of the GOVERNANCE role on a specific DALP token can create feeds for that token, provided the token supports the ISMART and ISMARTTokenAccessManaged interfaces. Does not apply to global feeds.
If neither condition is met, the factory reverts with UnauthorizedFeedCreation.
| Error | Cause |
|---|---|
UnauthorizedFeedCreation | Caller lacks FEEDS_MANAGER_ROLE and does not hold GOVERNANCE_ROLE on the subject token (or subject is address(0) and caller is not a feeds manager) |
Create an aggregator adapter
Adapters are stable-address proxies that resolve to the current underlying feed for a (subject, topic) pair. Consumers point at the adapter address instead of the feed directly. When you replace the underlying feed, the adapter automatically resolves to the new feed without consumers changing their configuration.
Prerequisites
Verify the adapter factory is installed:
curl "$DALP_API_URL/system/feeds/capabilities" \
-H "X-Api-Key: $API_KEY"Check that scalarFeedAggregatorAdapterFactory.installed is true.
Deploy the adapter
curl -X POST "$DALP_API_URL/system/feeds/adapters/create" \
-H "X-Api-Key: $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"subject": "0xTokenAddress",
"topicName": "PRICE/USD"
}'| Parameter | Type | Required | Description |
|---|---|---|---|
subject | address | Yes | The asset or entity |
topicName | string | At least one of topicName or topicId | Human-readable topic name |
topicId | string | At least one of topicName or topicId | The keccak256 hash of the topic name |
walletVerification | object | No (optional for API key auth) | Wallet verification for transaction signing — required for session-based auth only |
Response (synchronous, default):
{
"data": {
"adapterAddress": "0x...",
"subject": "0x...",
"topicId": "0x...",
"transactionHash": "0x..."
},
"meta": { "txHashes": ["0x..."] },
"links": { "self": "/system/feeds/adapters/create" }
}Add Prefer: respond-async for asynchronous processing (HTTP 202 with statusUrl for polling).
Permissions
Adapter creation follows the same two-path authorization as feed creation:
- Feeds Manager role (system-level) — can create adapters for any subject including global (address(0)).
- Governance role on subject token — can create adapters for their specific token. Does not apply to global subjects.
| Error | Cause |
|---|---|
UnauthorizedFeedCreation | Caller lacks FEEDS_MANAGER_ROLE and does not hold GOVERNANCE_ROLE on the subject token |
Register an external feed
Register an existing feed contract (e.g., a Chainlink price feed) in the directory so it can be discovered through the same (subject, topic) lookup as platform-managed feeds.
curl -X POST "$DALP_API_URL/system/feeds/register-external" \
-H "X-Api-Key: $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"subject": "0xTokenAddress",
"topicName": "PRICE/USD",
"feedAddress": "0xExternalFeedContract",
"kind": "SCALAR"
}'| Parameter | Type | Required | Description |
|---|---|---|---|
subject | address | Yes | The asset or entity |
topicName | string | At least one of topicName or topicId | Human-readable topic name |
topicId | string | At least one of topicName or topicId | The keccak256 hash of the topic name |
feedAddress | address | Yes | The external feed contract address |
kind | enum | Yes | Feed kind (SCALAR) |
walletVerification | object | No (optional for API key auth) | Wallet verification for transaction signing — required for session-based auth only |
Directory operations
Resolve a feed
Look up the feed registered for a (subject, topic) pair. You can use either topicName or topicId:
curl "$DALP_API_URL/system/feeds/resolve?subject=0xToken&topicName=PRICE/USD" \
-H "X-Api-Key: $API_KEY"Or with topicId:
curl "$DALP_API_URL/system/feeds/resolve?subject=0xToken&topicId=109530253..." \
-H "X-Api-Key: $API_KEY"Returns the feed address, kind, schema hash, adapter address (if one exists), and indexed data from DIDX.
Replace a feed
Swap the feed registered for a (subject, topic) pair with a different feed contract:
curl -X PUT "$DALP_API_URL/system/feeds/replace" \
-H "X-Api-Key: $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"subject": "0xTokenAddress",
"topicName": "PRICE/USD",
"newFeedAddress": "0xNewFeedContract",
"kind": "SCALAR"
}'| Parameter | Type | Required | Description |
|---|---|---|---|
subject | address | Yes | The asset or entity |
topicName | string | At least one of topicName or topicId | Human-readable topic name |
topicId | string | At least one of topicName or topicId | The keccak256 hash of the topic name |
newFeedAddress | address | Yes | The new feed contract address |
kind | enum | Yes | Feed kind (SCALAR) |
walletVerification | object | No (optional for API key auth) | Wallet verification for transaction signing — required for session-based auth only |
If an aggregator adapter exists for this (subject, topic), it automatically resolves to the new feed.
Remove a feed
Remove a feed registration from the directory:
curl -X DELETE "$DALP_API_URL/system/feeds/remove" \
-H "X-Api-Key: $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"subject": "0xTokenAddress",
"topicName": "PRICE/USD"
}'| Parameter | Type | Required | Description |
|---|---|---|---|
subject | address | Yes | The asset or entity |
topicName | string | At least one of topicName or topicId | Human-readable topic name |
topicId | string | At least one of topicName or topicId | The keccak256 hash of the topic name |
walletVerification | object | No (optional for API key auth) | Wallet verification for transaction signing — required for session-based auth only |