Extensions Overview
CRE Connect extensions are first-party Go modules that wrap the generic crec-sdk with service-specific helpers. Each extension provides three things:
- An operation builder that packs calldata for the service's smart contracts so you don't have to manage the ABI yourself.
- A typed event decoder so that
dta.SubscriptionRequestedarrives as a Go struct, not amap[string]any. - One-call watcher provisioning. CRE Connect ships pre-packaged watchers for the service so a single SDK call provisions every watcher the service needs.
Extensions are independent Go modules; you import only the ones you need.
Available extensions
| Extension | Module | Use when |
|---|---|---|
| DTA (Digital Transfer Agent) | github.com/smartcontractkit/crec-sdk-ext-dta | Tokenised funds: subscriptions, redemptions, distributor lifecycle. |
The DTA extension repository uses contract versioning: each deployed contract ABI is exposed as a separate import path (/v1, /v2, …) under the same Go module. Per the extension's README, this versioning matches the on-chain contract ABI version and is independent of Go module semantic versioning. The CRE Connect documentation focuses on the v2 import path; if you operate against v1 contracts, import the corresponding /v1 sub-package and consult the extension README for v1-specific operation signatures.
Anatomy of an extension
Take DTA v2 as the example. The module exposes three sub-packages:
crec-sdk-ext-dta/v2
├── / // Decode helper: v2.DecodeFromEvent
├── /events // Typed event structs + EventName constants + decoders
├── /operations // Extension client: PrepareXxxOperation builders
└── /watcher/bundle // bundle.Get(): service name + ABIs (consumed by CRE Connect)
v2/operations exposes an Extension struct with one PrepareXxxOperation method per on-chain action. Each method returns a *types.Operation ready to sign and send through crec-sdk/transact:
import "github.com/smartcontractkit/crec-sdk-ext-dta/v2/operations"
ext, err := operations.New(&operations.Options{
AccountAddress: smartAccount.Hex(),
DTARequestManagementAddress: managementAddr.Hex(),
DTARequestSettlementAddress: settlementAddr.Hex(),
})
op, err := ext.PrepareRequestSubscriptionOperation(fundAdmin, fundTokenId, amount, referenceID)
v2/events declares one Go struct per Solidity event (e.g. SubscriptionRequested, DistributorRegistered) and an EventName enum. The root v2.DecodeFromEvent(ctx, ev) helper combines watcher decoding with on-chain reference-data enrichment.
v2/watcher/bundle ships the service descriptor (name + ABIs) that CRE Connect uses to expose this service to watchers.CreateWithService. You typically don't import this package directly; only use it if you want to inspect the published service name or event list from your own code.
Why extensions matter
- No ABI bookkeeping. Calldata packing happens inside the extension; bumping a contract version is a single-module dependency upgrade.
- Typed events.
events.SubscriptionRequestedcarriesFundAdminAddr common.Address,Amount *big.Int, etc.: no string casting. - One-call watcher provisioning. Pass
Service: "dta.v2"towatchers.CreateWithServiceand CRE Connect sets up every watcher inbundle.Get().Events. - Backwards-compatible upgrades. When an event schema or operation signature changes, the extension version bumps and you get a compile error rather than a silent runtime drift.
Using an extension
Three integration points:
import (
crec "github.com/smartcontractkit/crec-sdk"
dta "github.com/smartcontractkit/crec-sdk-ext-dta/v2"
dtaop "github.com/smartcontractkit/crec-sdk-ext-dta/v2/operations"
)
client, _ := crec.NewClient(baseURL, apiKey)
ext, _ := dtaop.New(&dtaop.Options{
AccountAddress: smartAccount.Hex(),
DTARequestManagementAddress: mgmtAddr.Hex(),
DTARequestSettlementAddress: settleAddr.Hex(),
})
op, _ := ext.PrepareRequestSubscriptionOperation(fundAdmin, fundTokenId, amount, refID)
opr, _ := client.Transact.ExecuteOperation(ctx, channelID, signer, op, chainSelector)
events, _, _ := client.Events.Poll(ctx, channelID, nil)
for _, ev := range events {
decoded, err := dta.DecodeFromEvent(ctx, ev)
if err != nil { continue }
fmt.Println(decoded.EventName(), decoded.ConcreteEvent)
}
What's next
- DTA Overview: the
dta.v2extension end-to-end. - Concepts: Extensions: design philosophy and combination patterns.