@thru/sdk 0.2.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.abi.md +112 -0
- package/README.md +342 -0
- package/dist/abi/index.cjs +946 -0
- package/dist/abi/index.cjs.map +1 -0
- package/dist/abi/index.d.cts +331 -0
- package/dist/abi/index.d.ts +331 -0
- package/dist/abi/index.js +892 -0
- package/dist/abi/index.js.map +1 -0
- package/dist/abi/wasm/bundler/abi_reflect_wasm.d.ts +65 -0
- package/dist/abi/wasm/bundler/abi_reflect_wasm.js +5 -0
- package/dist/abi/wasm/bundler/abi_reflect_wasm_bg.js +412 -0
- package/dist/abi/wasm/bundler/abi_reflect_wasm_bg.wasm +0 -0
- package/dist/abi/wasm/bundler/abi_reflect_wasm_bg.wasm.d.ts +24 -0
- package/dist/abi/wasm/bundler/package.json +17 -0
- package/dist/abi/wasm/node/abi_reflect_wasm.d.ts +65 -0
- package/dist/abi/wasm/node/abi_reflect_wasm.js +425 -0
- package/dist/abi/wasm/node/abi_reflect_wasm_bg.wasm +0 -0
- package/dist/abi/wasm/node/abi_reflect_wasm_bg.wasm.d.ts +24 -0
- package/dist/abi/wasm/node/package.json +11 -0
- package/dist/abi/wasm/web/abi_reflect_wasm.d.ts +114 -0
- package/dist/abi/wasm/web/abi_reflect_wasm.js +499 -0
- package/dist/abi/wasm/web/abi_reflect_wasm_bg.wasm +0 -0
- package/dist/abi/wasm/web/abi_reflect_wasm_bg.wasm.d.ts +24 -0
- package/dist/abi/wasm/web/package.json +15 -0
- package/dist/chunk-CVBQ4UPL.js +3614 -0
- package/dist/chunk-CVBQ4UPL.js.map +1 -0
- package/dist/chunk-NSBPE2FW.js +15 -0
- package/dist/chunk-NSBPE2FW.js.map +1 -0
- package/dist/chunk-RL3Q6FDE.js +105 -0
- package/dist/chunk-RL3Q6FDE.js.map +1 -0
- package/dist/chunk-UDIXYJXC.js +260 -0
- package/dist/chunk-UDIXYJXC.js.map +1 -0
- package/dist/chunk-YQDWOMNO.js +271 -0
- package/dist/chunk-YQDWOMNO.js.map +1 -0
- package/dist/client-Cfi7zRLm.d.cts +1247 -0
- package/dist/client-worIo0a3.d.ts +1247 -0
- package/dist/client.cjs +3791 -0
- package/dist/client.cjs.map +1 -0
- package/dist/client.d.cts +7 -0
- package/dist/client.d.ts +7 -0
- package/dist/client.js +7 -0
- package/dist/client.js.map +1 -0
- package/dist/crypto/index.cjs +170 -0
- package/dist/crypto/index.cjs.map +1 -0
- package/dist/crypto/index.d.cts +60 -0
- package/dist/crypto/index.d.ts +60 -0
- package/dist/crypto/index.js +5 -0
- package/dist/crypto/index.js.map +1 -0
- package/dist/helpers/index.cjs +270 -0
- package/dist/helpers/index.cjs.map +1 -0
- package/dist/helpers/index.d.cts +15 -0
- package/dist/helpers/index.d.ts +15 -0
- package/dist/helpers/index.js +4 -0
- package/dist/helpers/index.js.map +1 -0
- package/dist/metafile-cjs.json +1 -0
- package/dist/metafile-esm.json +1 -0
- package/dist/proto/index.cjs +433 -0
- package/dist/proto/index.cjs.map +1 -0
- package/dist/proto/index.d.cts +435 -0
- package/dist/proto/index.d.ts +435 -0
- package/dist/proto/index.js +4 -0
- package/dist/proto/index.js.map +1 -0
- package/dist/sdk.cjs +4137 -0
- package/dist/sdk.cjs.map +1 -0
- package/dist/sdk.d.cts +36 -0
- package/dist/sdk.d.ts +36 -0
- package/dist/sdk.js +7 -0
- package/dist/sdk.js.map +1 -0
- package/dist/streaming_service_pb-DvCdJiCr.d.cts +4877 -0
- package/dist/streaming_service_pb-DvCdJiCr.d.ts +4877 -0
- package/dist/webcrypto-LTajLAad.d.cts +3 -0
- package/dist/webcrypto-LTajLAad.d.ts +3 -0
- package/package.json +88 -0
package/README.abi.md
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
# @thru/sdk/abi – WASM-backed ABI reflection
|
|
2
|
+
|
|
3
|
+
This package is now a thin TypeScript wrapper around the Rust `abi_reflect`
|
|
4
|
+
runtime. We compile the Rust crate to WebAssembly, ship both Node + bundler
|
|
5
|
+
targets, and expose a small async API for reflecting ABI YAML + binary payloads.
|
|
6
|
+
All layout math and validation run inside the Rust engine so TypeScript stays
|
|
7
|
+
lightweight and automatically inherits IR upgrades.
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Quick start
|
|
12
|
+
|
|
13
|
+
```ts
|
|
14
|
+
import { ensureWasmLoaded, formatReflection, reflect } from "@thru/sdk/abi";
|
|
15
|
+
import tokenAbi from "./abi/token_program.abi.yaml?raw";
|
|
16
|
+
|
|
17
|
+
async function example() {
|
|
18
|
+
await ensureWasmLoaded(); // formatter + reflector live inside WASM
|
|
19
|
+
|
|
20
|
+
const payload = new Uint8Array([0x01, 0, 0, 0, 0, 0, 0, 0]);
|
|
21
|
+
const reflection = await reflect(tokenAbi, "TokenInstruction", {
|
|
22
|
+
type: "binary",
|
|
23
|
+
value: payload,
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
console.log(reflection.value); // JSON emitted by abi_reflect
|
|
27
|
+
|
|
28
|
+
// Collapse the verbose JSON tree into something human-readable
|
|
29
|
+
const formatted = formatReflection(reflection);
|
|
30
|
+
console.log(formatted.value.payload.variant); // "initialize_mint"
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
example();
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
* The ABI text **must already be flattened** (imports resolved). The Rust
|
|
37
|
+
resolver enforces this.
|
|
38
|
+
* Results are JSON blobs straight from `serde_json`. They include the full type
|
|
39
|
+
info + value trees used by the CLI tooling.
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## Public API
|
|
44
|
+
|
|
45
|
+
| Function | Description |
|
|
46
|
+
| --- | --- |
|
|
47
|
+
| `reflect(abi: string, typeName: string, payload: { type: "binary", value: BinaryLike } \| { type: "hex", value: string })` | Reflects binary data (or hex) and returns the parsed JSON payload. |
|
|
48
|
+
| `formatReflection(raw: JsonValue)` | Delegates to the WASM formatter to collapse verbose JSON trees. Requires `ensureWasmLoaded()` (or any prior call to `reflect`) before use. |
|
|
49
|
+
| `buildLayoutIr(abi: string)` | Runs the shared Layout IR builder and returns the serialized IR document (schema version, per-type expressions, parameters). |
|
|
50
|
+
| `ensureWasmLoaded()` | Preloads the WASM bindings for callers that want to pay the initialization cost up-front. `reflect` calls it lazily. |
|
|
51
|
+
|
|
52
|
+
All helpers are async, because loading + instantiating the WASM module can touch
|
|
53
|
+
the filesystem (Node) or issue dynamic imports (bundlers).
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## WASM workflow
|
|
58
|
+
|
|
59
|
+
The generated artifacts are staged under `web/packages/sdk/wasm/abi/{bundler,node,web}`
|
|
60
|
+
before package builds. They are ignored in git, but copied into `dist/abi/wasm`
|
|
61
|
+
so published packages work without a local Rust toolchain. When `abi_reflect` or
|
|
62
|
+
the shared IR changes, rebuild everything with:
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
# From repo root
|
|
66
|
+
pnpm --filter @thru/sdk run build:wasm
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
That script runs `wasm-pack build` three times (bundler + node + web targets) inside
|
|
70
|
+
`rpc/abi/abi_reflect_wasm`, then copies the fresh outputs into
|
|
71
|
+
`web/packages/sdk/wasm/abi`. The regular `pnpm --filter @thru/sdk build` step runs
|
|
72
|
+
`tsup` and copies those WASM folders into `dist/abi/wasm` so published packages
|
|
73
|
+
resolve the dynamic imports automatically.
|
|
74
|
+
|
|
75
|
+
When developing inside the monorepo, Vitest loads the TypeScript sources
|
|
76
|
+
directly. The runtime detects when it is executing from `src/` and reaches for
|
|
77
|
+
`../wasm`, so make sure the synced artifacts exist before running the tests.
|
|
78
|
+
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
## Testing
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
pnpm --filter @thru/sdk test
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
Vitest exercises both `reflectHex` and `reflectBinary` against the
|
|
88
|
+
`SimpleStruct` compliance ABI plus `buildLayoutIr` to ensure the WASM bridge is
|
|
89
|
+
wired correctly. If you tweak the Rust runtime, rerun `pnpm build:wasm` so the
|
|
90
|
+
tests pick up the updated binaries.
|
|
91
|
+
|
|
92
|
+
---
|
|
93
|
+
|
|
94
|
+
## Development notes
|
|
95
|
+
|
|
96
|
+
* The TypeScript surface intentionally stays tiny; we no longer export the old
|
|
97
|
+
decoder/resolver classes. Future code should talk to the WASM bridge instead
|
|
98
|
+
of re-implementing reflection logic in JS.
|
|
99
|
+
* Browser vs. Node detection happens in `src/wasmBridge.ts`. Node loads the
|
|
100
|
+
`wasm/node` build via `createRequire`, while bundlers dynamically import the
|
|
101
|
+
`wasm/bundler` module.
|
|
102
|
+
* The JSON shape returned by `reflect*` matches `abi_reflect`'s CLI output, so
|
|
103
|
+
parity debugging can use the `abi-reflect` CLI under `rpc/abi/abi_reflect`.
|
|
104
|
+
* Layout IR consumers can feed `buildLayoutIr` into caches or ship a prebuilt
|
|
105
|
+
snapshot alongside the WASM runtime to guard against future schema changes.
|
|
106
|
+
|
|
107
|
+
---
|
|
108
|
+
|
|
109
|
+
Questions? Ping the thru-net ABI team (same folks maintaining
|
|
110
|
+
`rpc/abi/abi_reflect`). Whenever you extend the Rust reflection engine or shared IR,
|
|
111
|
+
regenerate the WASM artifacts and mention the change in `enums-fam-impl.md` so
|
|
112
|
+
tooling consumers know which version to depend on.
|
package/README.md
ADDED
|
@@ -0,0 +1,342 @@
|
|
|
1
|
+
# @thru/sdk
|
|
2
|
+
|
|
3
|
+
Typed TypeScript/JavaScript client for talking to the Thru blockchain. The SDK exposes rich domain models (blocks, accounts, transactions, events, proofs) that hide the underlying protobuf transport.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @thru/sdk
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
### TypeScript Configuration
|
|
12
|
+
|
|
13
|
+
For optimal import resolution, use modern module resolution:
|
|
14
|
+
|
|
15
|
+
```json
|
|
16
|
+
{
|
|
17
|
+
"compilerOptions": {
|
|
18
|
+
"moduleResolution": "bundler",
|
|
19
|
+
"module": "ESNext",
|
|
20
|
+
"target": "ES2020",
|
|
21
|
+
"isolatedModules": true
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
If you rely on Node’s ESM support without a bundler, use `"moduleResolution": "nodenext"`.
|
|
27
|
+
|
|
28
|
+
## Basic Usage
|
|
29
|
+
|
|
30
|
+
```ts
|
|
31
|
+
import { createThruClient } from "@thru/sdk";
|
|
32
|
+
import {
|
|
33
|
+
Account,
|
|
34
|
+
Block,
|
|
35
|
+
ChainEvent,
|
|
36
|
+
Transaction,
|
|
37
|
+
TransactionStatusSnapshot,
|
|
38
|
+
} from "@thru/sdk";
|
|
39
|
+
|
|
40
|
+
const thru = createThruClient({
|
|
41
|
+
baseUrl: "https://grpc-web.alphanet.thruput.org",
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
// Fetch the latest finalized block
|
|
45
|
+
const height = await thru.blocks.getBlockHeight();
|
|
46
|
+
const latestBlock: Block = await thru.blocks.get({ slot: height.finalized });
|
|
47
|
+
console.log(latestBlock.header.blockHash);
|
|
48
|
+
|
|
49
|
+
// Fetch an account – returns the Account domain object
|
|
50
|
+
const account: Account = await thru.accounts.get("taExampleAddress...");
|
|
51
|
+
console.log(account.meta?.balance);
|
|
52
|
+
|
|
53
|
+
// Build, sign, submit, and track a transaction
|
|
54
|
+
const { rawTransaction, signature } = await thru.transactions.buildAndSign({
|
|
55
|
+
feePayer: {
|
|
56
|
+
publicKey: "taFeePayerAddress...",
|
|
57
|
+
privateKey: feePayerSecretKeyBytes,
|
|
58
|
+
},
|
|
59
|
+
program: programIdentifierBytes,
|
|
60
|
+
});
|
|
61
|
+
await thru.transactions.send(rawTransaction);
|
|
62
|
+
|
|
63
|
+
// Track the transaction – emits domain snapshots
|
|
64
|
+
for await (const update of thru.streaming.trackTransaction(signature)) {
|
|
65
|
+
console.log(update.status, update.executionResult?.consumedComputeUnits);
|
|
66
|
+
if (update.statusCode === ConsensusStatus.FINALIZED) break;
|
|
67
|
+
}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## Client Configuration
|
|
71
|
+
|
|
72
|
+
`createThruClient` accepts advanced transport options so you can customize networking, interceptors, and default call behaviour:
|
|
73
|
+
|
|
74
|
+
```ts
|
|
75
|
+
const thru = createThruClient({
|
|
76
|
+
baseUrl: "https://grpc-web.alphanet.thruput.org",
|
|
77
|
+
transportOptions: {
|
|
78
|
+
useBinaryFormat: false,
|
|
79
|
+
defaultTimeoutMs: 10_000,
|
|
80
|
+
},
|
|
81
|
+
interceptors: [authInterceptor],
|
|
82
|
+
callOptions: {
|
|
83
|
+
timeoutMs: 5_000,
|
|
84
|
+
headers: [["x-team", "sdk"]],
|
|
85
|
+
},
|
|
86
|
+
});
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
- `transportOptions` are passed to `createGrpcWebTransport`. Provide custom fetch implementations, JSON/binary options, or merge additional interceptors.
|
|
90
|
+
- `interceptors` let you append cross-cutting logic (auth, metrics) without re-implementing transports.
|
|
91
|
+
- `callOptions` act as defaults for **every** RPC. You can set timeouts, headers, or a shared `AbortSignal`, and each module call merges in per-request overrides.
|
|
92
|
+
|
|
93
|
+
## Domain Models
|
|
94
|
+
|
|
95
|
+
The SDK revolves around immutable domain classes. They copy mutable buffers, expose clear invariants, and provide conversion helpers where needed.
|
|
96
|
+
|
|
97
|
+
| API surface | Domain class |
|
|
98
|
+
| --- | --- |
|
|
99
|
+
| Blocks | `Block`, `BlockHeader`, `BlockFooter` |
|
|
100
|
+
| Accounts | `Account`, `AccountMeta`, `AccountData` |
|
|
101
|
+
| Transactions | `Transaction`, `TransactionStatusSnapshot`, `TrackTransactionUpdate` |
|
|
102
|
+
| Events | `ChainEvent` |
|
|
103
|
+
| Proofs | `StateProof` |
|
|
104
|
+
| Height | `HeightSnapshot` |
|
|
105
|
+
| Node version | `VersionInfo` |
|
|
106
|
+
|
|
107
|
+
All classes are exported from the root package for easy access:
|
|
108
|
+
|
|
109
|
+
```ts
|
|
110
|
+
import { Block, Account, ChainEvent } from "@thru/sdk";
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### Primitives
|
|
114
|
+
|
|
115
|
+
`Pubkey` and `Signature` wrap the 32-byte Ed25519 public key and 64-byte signature primitives, respectively. They centralize validation, conversion, and proto interop so you can work with either Thru-formatted strings (`ta...` / `ts...`), hex, or raw bytes without sprinkling helpers throughout your app.
|
|
116
|
+
|
|
117
|
+
```ts
|
|
118
|
+
import { Pubkey, Signature } from "@thru/sdk";
|
|
119
|
+
|
|
120
|
+
const payer = Pubkey.from("taDs2..."); // accepts ta string, hex, or Uint8Array
|
|
121
|
+
const sig = Signature.from("ts8Lk..."); // accepts ts string, hex, or Uint8Array
|
|
122
|
+
|
|
123
|
+
payer.toBytes(); // defensive copy
|
|
124
|
+
payer.toThruFmt(); // "ta..." string
|
|
125
|
+
payer.toProtoPubkey(); // thru.common.v1.Pubkey
|
|
126
|
+
payer.toProtoTaPubkey(); // thru.common.v1.TaPubkey
|
|
127
|
+
|
|
128
|
+
sig.toBytes();
|
|
129
|
+
sig.toThruFmt(); // "ts..." string
|
|
130
|
+
sig.toProtoSignature(); // thru.common.v1.Signature
|
|
131
|
+
sig.toProtoTsSignature(); // thru.common.v1.TsSignature
|
|
132
|
+
|
|
133
|
+
// Helper namespace now returns these domain objects:
|
|
134
|
+
const parsed = sdk.helpers.createPubkey("taFeePayerAddress...");
|
|
135
|
+
const signature = sdk.helpers.createSignature(sigBytes);
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
The bound client accepts either raw bytes or the new primitives; call `.toBytes()` on `Pubkey`/`Signature` when you need to interop with legacy code.
|
|
139
|
+
|
|
140
|
+
## View Options
|
|
141
|
+
|
|
142
|
+
When fetching resources, you can control which parts of the resource are returned using view options. This allows you to optimize network usage by only fetching the data you need.
|
|
143
|
+
|
|
144
|
+
### AccountView
|
|
145
|
+
|
|
146
|
+
Controls which sections of account resources are returned:
|
|
147
|
+
|
|
148
|
+
```ts
|
|
149
|
+
import { AccountView } from "@thru/sdk";
|
|
150
|
+
|
|
151
|
+
// Fetch only the account address (lightweight existence check)
|
|
152
|
+
const account = await thru.accounts.get(address, {
|
|
153
|
+
view: AccountView.PUBKEY_ONLY,
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
// Fetch only account metadata (balance, flags, owner, etc.)
|
|
157
|
+
const account = await thru.accounts.get(address, {
|
|
158
|
+
view: AccountView.META_ONLY,
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
// Fetch only account data bytes (program data)
|
|
162
|
+
const account = await thru.accounts.get(address, {
|
|
163
|
+
view: AccountView.DATA_ONLY,
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
// Fetch everything: address, metadata, and data (default)
|
|
167
|
+
const account = await thru.accounts.get(address, {
|
|
168
|
+
view: AccountView.FULL,
|
|
169
|
+
});
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
| View Option | Returns | Use Case |
|
|
173
|
+
| --- | --- | --- |
|
|
174
|
+
| `AccountView.PUBKEY_ONLY` | Only the account `address` | Quick existence check |
|
|
175
|
+
| `AccountView.META_ONLY` | `address` + `meta` (balance, flags, owner, dataSize, seq, nonce) | Display account summary without data |
|
|
176
|
+
| `AccountView.DATA_ONLY` | `address` + `data` (raw bytes) | Fetch program data without metadata |
|
|
177
|
+
| `AccountView.FULL` | `address` + `meta` + `data` | Complete account information |
|
|
178
|
+
|
|
179
|
+
### BlockView
|
|
180
|
+
|
|
181
|
+
Controls how much of a block resource is returned:
|
|
182
|
+
|
|
183
|
+
```ts
|
|
184
|
+
import { BlockView } from "@thru/sdk";
|
|
185
|
+
|
|
186
|
+
// Fetch only block header (slot, hash, producer, etc.)
|
|
187
|
+
const block = await thru.blocks.get({ slot }, {
|
|
188
|
+
view: BlockView.HEADER_ONLY,
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
// Fetch header and footer (execution status)
|
|
192
|
+
const block = await thru.blocks.get({ slot }, {
|
|
193
|
+
view: BlockView.HEADER_AND_FOOTER,
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
// Fetch only block body (transactions)
|
|
197
|
+
const block = await thru.blocks.get({ slot }, {
|
|
198
|
+
view: BlockView.BODY_ONLY,
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
// Fetch everything: header, body, and footer (default)
|
|
202
|
+
const block = await thru.blocks.get({ slot }, {
|
|
203
|
+
view: BlockView.FULL,
|
|
204
|
+
});
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
| View Option | Returns | Use Case |
|
|
208
|
+
| --- | --- | --- |
|
|
209
|
+
| `BlockView.HEADER_ONLY` | Only block `header` (metadata) | Display block summary without transactions |
|
|
210
|
+
| `BlockView.HEADER_AND_FOOTER` | `header` + `footer` (execution status) | Check execution status without transactions |
|
|
211
|
+
| `BlockView.BODY_ONLY` | Only block `body` (transactions) | Fetch transactions without header metadata |
|
|
212
|
+
| `BlockView.FULL` | `header` + `body` + `footer` | Complete block information |
|
|
213
|
+
|
|
214
|
+
### TransactionView
|
|
215
|
+
|
|
216
|
+
Controls how much of a transaction resource is returned:
|
|
217
|
+
|
|
218
|
+
```ts
|
|
219
|
+
import { TransactionView } from "@thru/sdk";
|
|
220
|
+
|
|
221
|
+
// Fetch only transaction signature
|
|
222
|
+
const tx = await thru.transactions.get(signature, {
|
|
223
|
+
view: TransactionView.SIGNATURE_ONLY,
|
|
224
|
+
});
|
|
225
|
+
|
|
226
|
+
// Fetch only transaction header (signature, fee payer, etc.)
|
|
227
|
+
const tx = await thru.transactions.get(signature, {
|
|
228
|
+
view: TransactionView.HEADER_ONLY,
|
|
229
|
+
});
|
|
230
|
+
|
|
231
|
+
// Fetch header and body (instructions)
|
|
232
|
+
const tx = await thru.transactions.get(signature, {
|
|
233
|
+
view: TransactionView.HEADER_AND_BODY,
|
|
234
|
+
});
|
|
235
|
+
|
|
236
|
+
// Fetch everything: header, body, and execution results (default)
|
|
237
|
+
const tx = await thru.transactions.get(signature, {
|
|
238
|
+
view: TransactionView.FULL,
|
|
239
|
+
});
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
| View Option | Returns | Use Case |
|
|
243
|
+
| --- | --- | --- |
|
|
244
|
+
| `TransactionView.SIGNATURE_ONLY` | Only transaction `signature` | Quick existence check |
|
|
245
|
+
| `TransactionView.HEADER_ONLY` | Only transaction `header` (signature, fee payer, compute budget) | Display transaction summary without instructions |
|
|
246
|
+
| `TransactionView.HEADER_AND_BODY` | `header` + `body` (instructions) | Fetch transaction without execution results |
|
|
247
|
+
| `TransactionView.FULL` | `header` + `body` + execution results | Complete transaction information |
|
|
248
|
+
|
|
249
|
+
**Note:** If no view is specified, the default is `FULL` for all resource types.
|
|
250
|
+
|
|
251
|
+
## Streaming APIs
|
|
252
|
+
|
|
253
|
+
Every streaming endpoint yields an async iterable of domain models:
|
|
254
|
+
|
|
255
|
+
```ts
|
|
256
|
+
// Blocks
|
|
257
|
+
for await (const { block } of thru.streaming.streamBlocks()) {
|
|
258
|
+
console.log(block.header.slot);
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
// Account updates
|
|
262
|
+
for await (const { update } of thru.streaming.streamAccountUpdates("taAddress")) {
|
|
263
|
+
if (update.kind === "snapshot") {
|
|
264
|
+
console.log(update.snapshot.account.meta?.balance);
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
// Events
|
|
269
|
+
for await (const { event } of thru.streaming.streamEvents()) {
|
|
270
|
+
console.log((event as ChainEvent).timestampNs);
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
// Transaction tracking
|
|
274
|
+
for await (const update of thru.streaming.trackTransaction(signature)) {
|
|
275
|
+
console.log(update.status, update.executionResult?.consumedComputeUnits);
|
|
276
|
+
}
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
## Filters
|
|
280
|
+
|
|
281
|
+
Server-side filtering is supported everywhere via CEL expressions:
|
|
282
|
+
|
|
283
|
+
```ts
|
|
284
|
+
import { Filter, FilterParamValue } from "@thru/sdk";
|
|
285
|
+
|
|
286
|
+
const ownerFilter = new Filter({
|
|
287
|
+
expression: "account.meta.owner.value == params.owner",
|
|
288
|
+
params: {
|
|
289
|
+
owner: FilterParamValue.pubkey("taExampleAddress..."),
|
|
290
|
+
min_balance: FilterParamValue.uint(1_000_000n),
|
|
291
|
+
},
|
|
292
|
+
});
|
|
293
|
+
|
|
294
|
+
const accounts = await thru.accounts.list({ filter: ownerFilter });
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
Accepted parameter kinds:
|
|
298
|
+
- `stringValue`
|
|
299
|
+
- `bytesValue`
|
|
300
|
+
- `boolValue`
|
|
301
|
+
- `intValue`
|
|
302
|
+
- `doubleValue`
|
|
303
|
+
- `uintValue`
|
|
304
|
+
- `pubkeyValue`
|
|
305
|
+
- `signatureValue`
|
|
306
|
+
- `taPubkeyValue`
|
|
307
|
+
- `tsSignatureValue`
|
|
308
|
+
|
|
309
|
+
Functions that take filters:
|
|
310
|
+
- List APIs: `thru.accounts.list`, `thru.blocks.list`, `thru.transactions.listForAccount`
|
|
311
|
+
- Streams: `thru.streaming.streamBlocks`, `thru.streaming.streamAccountUpdates`, `thru.streaming.streamTransactions`, `thru.streaming.streamEvents`
|
|
312
|
+
|
|
313
|
+
Use the helper constructors on `FilterParamValue` to safely build parameters from raw bytes, ta/ts-encoded strings, or simple numbers.
|
|
314
|
+
|
|
315
|
+
## Modules Overview
|
|
316
|
+
|
|
317
|
+
- `thru.blocks` — fetch/stream blocks and height snapshots
|
|
318
|
+
- `thru.accounts` — read account state or build create-account transactions
|
|
319
|
+
- `thru.transactions` — build, sign, submit, track, and inspect transactions
|
|
320
|
+
- `thru.events` — query event history
|
|
321
|
+
- `thru.proofs` — generate state proofs
|
|
322
|
+
- `thru.consensus` — build version contexts and stringify consensus states
|
|
323
|
+
- `thru.streaming` — streaming wrappers for blocks, accounts, transactions, events
|
|
324
|
+
- `thru.helpers` — address, signature, and block-hash conversion helpers
|
|
325
|
+
|
|
326
|
+
The public surface is fully domain-based; reaching for lower-level protobuf structures is no longer necessary.
|
|
327
|
+
|
|
328
|
+
## Streaming helpers
|
|
329
|
+
|
|
330
|
+
Async iterable utilities make it easier to consume streaming APIs:
|
|
331
|
+
|
|
332
|
+
```ts
|
|
333
|
+
import { collectStream, firstStreamValue } from "@thru/sdk";
|
|
334
|
+
|
|
335
|
+
const updates = await collectStream(thru.streaming.streamBlocks({ startSlot: height.finalized }), {
|
|
336
|
+
limit: 5,
|
|
337
|
+
});
|
|
338
|
+
|
|
339
|
+
const firstEvent = await firstStreamValue(thru.streaming.streamEvents());
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
`collectStream` gathers values (optionally respecting `AbortSignal`s), `firstStreamValue` returns the first item, and `forEachStreamValue` lets you run async handlers for each streamed update.
|