Server — Registry + Bridges
1. Instantiate the Server ClientDirect link to 1. Instantiate the Server Client
- TypeScript
- Go
- Python
import { HCS7Client, HCS7ConfigType } from '@hashgraphonline/standards-sdk';
const hcs7 = new HCS7Client({
network: 'testnet',
operatorId: process.env.HEDERA_ACCOUNT_ID!,
operatorKey: process.env.HEDERA_PRIVATE_KEY!,
});
import (
"os"
"github.com/hashgraph-online/standards-sdk-go/pkg/hcs7"
)
client, err := hcs7.NewClient(hcs7.ClientConfig{
Network: "testnet",
OperatorAccountID: os.Getenv("HEDERA_ACCOUNT_ID"),
OperatorPrivateKey: os.Getenv("HEDERA_PRIVATE_KEY"),
})
import os
from standards_sdk_py.hcs7 import Hcs7Client
client = Hcs7Client(
network="testnet",
operator_id=os.environ["HEDERA_ACCOUNT_ID"],
operator_private_key=os.environ["HEDERA_PRIVATE_KEY"],
)
The client wraps all topic/transaction plumbing: memo generation (hcs-7:indexed:{ttl}), signing, and receipt handling. Call hcs7.close() when you finish.
2. Create a Registry TopicDirect link to 2. Create a Registry Topic
- TypeScript
- Go
- Python
const registry = await hcs7.createRegistry({ ttl: 86_400, submitKey: true });
if (!registry.success || !registry.topicId) throw new Error(registry.error);
console.log('Registry Topic:', registry.topicId);
registry, err := client.CreateRegistry(ctx, hcs7.CreateRegistryOptions{
TTL: 86400,
UseOperatorAsSubmit: true,
})
if err != nil || !registry.Success {
panic("failed to create registry")
}
fmt.Println("Registry Topic:", registry.TopicID)
registry = client.create_registry(ttl=86400, use_operator_as_submit=True)
fmt.println("Registry Topic:", registry.topic_id)
ttlmust be ≥ 3600 seconds.submitKey: truereuses the operator key as the topic submit key. Pass aPrivateKeyorstringto use a dedicated key.
3. Register EVM + WASM ConfigsDirect link to 3. Register EVM + WASM Configs
- TypeScript
- Go
- Python
await hcs7.registerConfig({
registryTopicId: registry.topicId,
memo: 'LaunchPage minted',
config: {
type: HCS7ConfigType.EVM,
contractAddress: '0x1d67aaf7f7e8d806bbeba24c4dea24808e1158b8',
abi: {
name: 'minted',
inputs: [],
outputs: [{ name: '', type: 'uint64' }],
stateMutability: 'view',
type: 'function',
},
},
});
await hcs7.registerConfig({
registryTopicId: registry.topicId,
memo: 'mint router',
config: {
type: HCS7ConfigType.WASM,
wasmTopicId: '0.0.5269810',
inputType: {
stateData: {
minted: 'number',
tokensRemaining: 'number',
},
},
outputType: {
type: 'string',
format: 'topic-id',
},
},
});
_, err = client.RegisterConfig(ctx, hcs7.RegisterConfigOptions{
RegistryTopicID: registry.TopicID,
Memo: "LaunchPage minted",
Type: hcs7.ConfigTypeEVM,
EVM: &hcs7.EvmConfigPayload{
ContractAddress: "0x1d67aaf7f7e8d806bbeba24c4dea24808e1158b8",
Abi: hcs7.AbiDefinition{
Name: "minted",
Inputs: []hcs7.AbiIO{},
Outputs: []hcs7.AbiIO{{Name: "", Type: "uint64"}},
StateMutability: "view",
Type: "function",
},
},
})
_, err = client.RegisterConfig(ctx, hcs7.RegisterConfigOptions{
RegistryTopicID: registry.TopicID,
Memo: "mint router",
Type: hcs7.ConfigTypeWASM,
WASM: &hcs7.WasmConfigPayload{
WasmTopicID: "0.0.5269810",
InputType: map[string]any{
"stateData": map[string]string{
"minted": "number",
"tokensRemaining": "number",
},
},
OutputType: map[string]any{
"type": "string",
"format": "topic-id",
},
},
})
client.register_config(registry_topic_id=registry.topic_id, memo="LaunchPage minted", type=hcs7.CONFIG_TYPE_E_V_M, e_v_m=&{"contract_address": "0x1d67aaf7f7e8d806bbeba24c4dea24808e1158b8", "abi": hcs7.AbiDefinition{ Name: "minted", "inputs": []hcs7.AbiIO{}, Outputs: []{"name": "", "type": "uint64"}}, StateMutability: "view", Type: "function", }, })
client.register_config(registry_topic_id=registry.topic_id, memo="mint router", type=hcs7.CONFIG_TYPE_W_A_S_M, w_a_s_m=&{"wasm_topic_id": "0.0.5269810", "input_type": map[string]any{ "stateData": map[string]string{ "minted": "number", "tokensRemaining": "number"}, }, OutputType: map[string]any{ "type": "string", "format": "topic-id", }, })
Each registration writes a register-config message into the same HCS‑7 topic the toolkit polls.
4. Register Metadata TargetsDirect link to 4. Register Metadata Targets
- TypeScript
- Go
- Python
await hcs7.registerMetadata({
registryTopicId: registry.topicId,
metadataTopicId: '0.0.3717738',
weight: 1,
tags: ['odd'],
memo: 'odd artwork',
});
await hcs7.registerMetadata({
registryTopicId: registry.topicId,
metadataTopicId: '0.0.3717746',
weight: 1,
tags: ['even'],
memo: 'even artwork',
});
_, err = client.RegisterMetadata(ctx, hcs7.RegisterMetadataOptions{
RegistryTopicID: registry.TopicID,
MetadataTopicID: "0.0.3717738",
Weight: 1,
Tags: []string{"odd"},
Memo: "odd artwork",
})
_, err = client.RegisterMetadata(ctx, hcs7.RegisterMetadataOptions{
RegistryTopicID: registry.TopicID,
MetadataTopicID: "0.0.3717746",
Weight: 1,
Tags: []string{"even"},
Memo: "even artwork",
})
client.register_metadata(registry_topic_id=registry.topic_id, metadata_topic_id="0.0.3717738", weight=1, tags=[][], memo="odd artwork")
client.register_metadata(registry_topic_id=registry.topic_id, metadata_topic_id="0.0.3717746", weight=1, tags=[][], memo="even artwork")
5. Query the RegistryDirect link to 5. Query the Registry
- TypeScript
- Go
- Python
const topic = await hcs7.getRegistry(registry.topicId, { limit: 50 });
topic.entries.forEach(entry => {
console.log(entry.sequenceNumber, entry.message.op, entry.message.m);
});
topic, err := client.GetRegistry(ctx, registry.TopicID, shared.QueryOptions{Limit: 50})
if err == nil {
for _, entry := range topic.Entries {
fmt.Println(entry.SequenceNumber, entry.Message.Op, entry.Message.M)
}
}
topic = client.get_registry(registry.topic_id, limit=50)
# if err == nil {
for entry in topic.Entries :
fmt.println(entry.SEQUENCE_NUMBER, entry.Message.Op, entry.Message.M)
getRegistry reads the Mirror Node, validates each message against the HCS‑7 schema, and returns typed entries.
6. Use the Bridges for State + RoutingDirect link to 6. Use the Bridges for State + Routing
Note: The EVM and WASM Bridges are currently available in the TypeScript SDK.
EVMBridgeDirect link to EVMBridge
- TypeScript
- Go
- Python
import { EVMBridge } from '@hashgraphonline/standards-sdk';
const evm = new EVMBridge('testnet');
const { result } = await evm.executeCommand({
c: {
contractAddress: '0x1d67aaf7f7e8d806bbeba24c4dea24808e1158b8',
abi: {
name: 'minted',
inputs: [],
outputs: [{ name: '', type: 'uint64' }],
stateMutability: 'view',
type: 'function',
},
},
});
console.log('Minted so far:', result.values?.[0]);
// Note: EVMBridge is available in the TypeScript SDK.
// See the TypeScript tab for examples.
from standards_sdk_py.hcs7 import Hcs7Client
# Equivalent Python usage — see Python SDK docs for details
Swap in RedisCache if you need a shared cache across processes:
- TypeScript
- Go
- Python
import { RedisCache } from '@hashgraphonline/standards-sdk';
const evm = new EVMBridge('testnet', undefined, new RedisCache({ host: '127.0.0.1' }));
// Note: EVMBridge is available in the TypeScript SDK.
from standards_sdk_py.hcs7 import Hcs7Client
# Equivalent Python usage — see Python SDK docs for details
WasmBridgeDirect link to WasmBridge
- TypeScript
- Go
- Python
import { WasmBridge } from '@hashgraphonline/standards-sdk';
const wasm = new WasmBridge();
const wasmBytes = await fetch('https://kiloscribe.com/api/inscription-cdn/0.0.5269810?network=testnet').then(r => r.arrayBuffer());
await wasm.initWasm(wasmBytes);
const messages = await hcs7.getRegistry(registry.topicId, { limit: 100 });
const stateData = {
minted: '42',
tokensRemaining: '58',
};
const topicId = wasm.executeWasm(stateData, messages.entries.map(e => e.message));
console.log('Selected metadata topic:', topicId);
// Note: WasmBridge is available in the TypeScript SDK.
// See the TypeScript tab for examples.
from standards_sdk_py.hcs7 import Hcs7Client
# Equivalent Python usage — see Python SDK docs for details
7. Low-Level TransactionsDirect link to 7. Low-Level Transactions
When you need to integrate with other toolchains (e.g., schedule a submit in HCS‑10 or build transactions inside the Agent Kit), use the helpers in src/hcs-7/tx.ts.
buildHcs7CreateRegistryTxbuildHcs7SubmitMessageTxbuildHcs7EvmMessageTxbuildHcs7WasmMessageTx
Each helper serializes the payload (p: 'hcs-7', op, etc.) so you only need to sign/send it with the Hedera SDK or another orchestration tool.
8. Fetching Metadata / WASM from KiloScribeDirect link to 8. Fetching Metadata / WASM from KiloScribe
Any topic you inscribe with the Standards SDK (metadata or WASM) is mirrored to the CDN. Use it when rendering hashinals or downloading routers server-side:
- TypeScript
- Go
- Python
const topicId = '0.0.3717746';
const res = await fetch(
`https://kiloscribe.com/api/inscription-cdn/${topicId}?network=testnet`,
{ headers: { Accept: 'application/json' } },
);
const metadata = await res.json();
topicID := "0.0.3717746"
url := fmt.Sprintf("https://kiloscribe.com/api/inscription-cdn/%s?network=testnet", topicID)
req, _ := http.NewRequest("GET", url, nil)
req.Header.Set("Accept", "application/json")
res, err := http.DefaultClient.Do(req)
if err == nil {
defer res.Body.Close()
var metadata map[string]any
json.NewDecoder(res.Body).Decode(&metadata)
}
topic_id = "0.0.3717746"
url = fmt.sprintf("https://kiloscribe.com/api/inscription-cdn/%s?network=testnet", topicID)
req = http.new_request("GET", url, None)
# req.Header.Set("Accept", "application/json")
# res, err := http.DefaultClient.Do(req)
# if err == nil {
# defer res.Body.Close()
# var metadata map[string]any
json.new_decoder(res.Body).Decode(&metadata)
For WASM binaries:
- TypeScript
- Go
- Python
const wasmTopicId = '0.0.5269810';
const wasmBytes = await fetch(
`https://kiloscribe.com/api/inscription-cdn/${wasmTopicId}?network=testnet`,
{ headers: { Accept: 'application/wasm' } },
).then(r => r.arrayBuffer());
wasmTopicID := "0.0.5269810"
url := fmt.Sprintf("https://kiloscribe.com/api/inscription-cdn/%s?network=testnet", wasmTopicID)
req, _ := http.NewRequest("GET", url, nil)
req.Header.Set("Accept", "application/wasm")
res, err := http.DefaultClient.Do(req)
if err == nil {
defer res.Body.Close()
wasmBytes, _ := io.ReadAll(res.Body)
}
wasm_topic_id = "0.0.5269810"
url = fmt.sprintf("https://kiloscribe.com/api/inscription-cdn/%s?network=testnet", wasmTopicID)
req = http.new_request("GET", url, None)
# req.Header.Set("Accept", "application/wasm")
# res, err := http.DefaultClient.Do(req)
# if err == nil {
# defer res.Body.Close()
wasmBytes = io.read_all(res.BODY)
You can still pull messages directly from HCS topics if you prefer, but the CDN saves repeated decoding.