Skip to content

Solana SDK#278

Merged
ernest-nowacki merged 14 commits into
mainfrom
feat/solana-sdk
Jul 2, 2026
Merged

Solana SDK#278
ernest-nowacki merged 14 commits into
mainfrom
feat/solana-sdk

Conversation

@ernest-nowacki

@ernest-nowacki ernest-nowacki commented Jun 22, 2026

Copy link
Copy Markdown
Collaborator

Add Solana binding generator support to the TypeScript SDK

Background

This PR brings support for Solana write-report workflows to the TypeScript SDK. It ships a solana capability client, a bindings package with Borsh/forwarder helpers, and a code generator in cre-cli (separate PR) that turns an Anchor IDL into a typed TS binding class.


What's added

1. Protobuf-generated Solana capability client

src/generated-sdk/capabilities/blockchain/solana/v1alpha/client_sdk_gen.ts contains the generated ClientCapability (re-exported as SolanaClient) that wraps the solana@1.0.0 capability's WriteReport RPC. It follows the same wrapped-input pattern used by the EVM client.

2. Solana helper library

src/sdk/utils/capabilities/blockchain/solana/solana-helpers.ts provides the TypeScript helpers inspired by the Go bindings package:

  • solanaAddressToBytes — validates and decodes a base58 address to its 32 raw bytes.
  • solanaAccountMeta — constructs an SolanaAccountMeta from a base58 string or raw bytes.
  • solanaAccountMetasToJson — serialises account metas to the capability's protobuf JSON wire format (base64 public keys).
  • calculateAccountsHash — SHA-256 over the concatenated public keys of the remaining accounts. This hash is embedded in the report and verified on-chain by the keystone-forwarder.
  • encodeForwarderReport — Borsh-encodes the 32-byte account hash followed by the u32-LE payload length and payload bytes.
  • encodeBorshVecU32 — prepends a u32-LE element count to a sequence of pre-encoded payloads for the Anchor Vec wire format.
  • prepareSolanaReportRequest — convenience wrapper around the shared prepareReportRequestFromBytes helper, pre-configured with the correct encoder/signing/hashing algorithm names for the Solana capability.

3. Chain selectors

Generated chain selector entries for solana-mainnet, solana-devnet, and solana-testnet.

4. Test mock

src/sdk/test/generated/capabilities/blockchain/solana/v1alpha/solana_mock_gen.ts — generated SolanaMock class. Works the same way as EvmMock: call SolanaMock.testInstance(chainSelector) to get a per-chain instance and set its writeReport handler.

src/sdk/test/solana-contract-mock.tsaddSolanaContractMock, the Solana counterpart to addContractMock. Routes write-report calls to typed per-program handlers by matching the receiver field (program ID bytes). Multiple programs can be registered on a single SolanaMock via chaining.

5. TypeScript binding generator in cre-cli

cmd/generate-bindings/solana/tsbindgen.go (in the CLI repo) generates two files from an Anchor IDL. More details in cre-cli PR: smartcontractkit/cre-cli#502

6. Example workflow

packages/cre-sdk-examples/src/workflows/solana-onchain-write/ — a complete cron-triggered workflow that uses a generated DataStorage binding to call writeReportFromUserData, demonstrating the end-to-end flow.


New dependencies

@solana/addresses and @solana/codecs

These are part of Solana's official web3.js v2 library, published as independent scoped packages. They were chosen for the same reason viem was chosen for EVM: they are the idiomatic, well-maintained, tree-shakeable primitives for the Solana ecosystem.

  • @solana/addresses handles base58 address validation and encoding. It provides a branded Address type that makes invalid addresses a compile-time error, and the getAddressEncoder / getAddressCodec used both in the helpers and in generated bindings.
  • @solana/codecs provides the Borsh/Anchor codec building blocks — getStructCodec, getArrayCodec, getU32Codec, getU64Codec, addCodecSizePrefix, getBytesCodec, getUtf8Codec, and the rest of the codec primitives. These are what the binding generator emits; every generated codec expression assembles them directly, so no additional Borsh runtime is needed.

Both are already widely used in the Solana developer ecosystem and have stable APIs.

@noble/hashes

calculateAccountsHash needs SHA-256. The TypeScript SDK compiles to WASM and runs inside Javy, where neither Node's crypto module nor the browser's SubtleCrypto is available. @noble/hashes is a zero-dependency, pure-JavaScript cryptography library that runs in any JS environment including a WASM sandbox. It is already the de-facto standard for pure-JS hashing in the Web3 ecosystem (used by viem, @solana/addresses, and many others), and its sha256 from @noble/hashes/sha2 and concatBytes from @noble/hashes/utils are the only two imports needed. There's also cre-templates PR in works that would suggest using @noble for whenever hashing is required.


What's not included

I haven't tested or covered specifically log trigger functionality for Solana. That would come in the follow up PR.

@ernest-nowacki ernest-nowacki marked this pull request as ready for review June 30, 2026 08:46
@ernest-nowacki ernest-nowacki requested review from a team as code owners June 30, 2026 08:46
@ernest-nowacki ernest-nowacki merged commit c381f84 into main Jul 2, 2026
15 checks passed
@ernest-nowacki ernest-nowacki deleted the feat/solana-sdk branch July 2, 2026 06:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants