cantonjs-react 0.0.1 → 0.2.0

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.
Files changed (2) hide show
  1. package/README.md +179 -0
  2. package/package.json +2 -2
package/README.md ADDED
@@ -0,0 +1,179 @@
1
+ # cantonjs-react
2
+
3
+ React hooks for Canton Network dApps, powered by [TanStack Query](https://tanstack.com/query).
4
+
5
+ [![npm version](https://img.shields.io/npm/v/cantonjs-react.svg)](https://www.npmjs.com/package/cantonjs-react)
6
+ [![License](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](https://github.com/merged-one/cantonjs/blob/main/LICENSE)
7
+
8
+ ## Install
9
+
10
+ ```bash
11
+ npm install cantonjs cantonjs-react @tanstack/react-query
12
+ ```
13
+
14
+ ## Quick Start
15
+
16
+ ```tsx
17
+ import { CantonProvider, useContracts, useCreateContract } from 'cantonjs-react'
18
+ import { createLedgerClient, jsonApi } from 'cantonjs'
19
+
20
+ const client = createLedgerClient({
21
+ transport: jsonApi({ url: 'http://localhost:7575', token: jwt }),
22
+ actAs: 'Alice::1234',
23
+ })
24
+
25
+ function App() {
26
+ return (
27
+ <CantonProvider client={client}>
28
+ <AssetList />
29
+ </CantonProvider>
30
+ )
31
+ }
32
+
33
+ function AssetList() {
34
+ const { data: assets, isLoading } = useContracts({
35
+ templateId: '#my-pkg:Main:Asset',
36
+ })
37
+
38
+ const { mutate: create, isPending } = useCreateContract({
39
+ templateId: '#my-pkg:Main:Asset',
40
+ })
41
+
42
+ if (isLoading) return <div>Loading...</div>
43
+
44
+ return (
45
+ <div>
46
+ <button
47
+ disabled={isPending}
48
+ onClick={() => create({ createArguments: { owner: 'Alice', value: 100 } })}
49
+ >
50
+ Create Asset
51
+ </button>
52
+ <ul>
53
+ {assets?.map(c => (
54
+ <li key={c.createdEvent.contractId}>
55
+ {JSON.stringify(c.createdEvent.createArgument)}
56
+ </li>
57
+ ))}
58
+ </ul>
59
+ </div>
60
+ )
61
+ }
62
+ ```
63
+
64
+ ## Hooks
65
+
66
+ ### `useContracts(options)`
67
+
68
+ Query active contracts with automatic caching and deduplication.
69
+
70
+ ```tsx
71
+ const { data, isLoading, error } = useContracts({
72
+ templateId: '#my-pkg:Main:Asset',
73
+ enabled: true, // optional, default true
74
+ refetchInterval: 5000, // optional, auto-refetch in ms
75
+ })
76
+ ```
77
+
78
+ ### `useCreateContract(options)`
79
+
80
+ Mutation hook for creating contracts. Automatically invalidates related queries on success.
81
+
82
+ ```tsx
83
+ const { mutate: create, isPending, error } = useCreateContract({
84
+ templateId: '#my-pkg:Main:Asset',
85
+ onSuccess: (event) => console.log('Created:', event.contractId),
86
+ })
87
+
88
+ create({ createArguments: { owner: 'Alice', value: 100 } })
89
+ ```
90
+
91
+ ### `useExercise(options)`
92
+
93
+ Mutation hook for exercising choices. Automatically invalidates related queries on success.
94
+
95
+ ```tsx
96
+ const { mutate: exercise, isPending } = useExercise({
97
+ templateId: '#my-pkg:Main:Asset',
98
+ choice: 'Transfer',
99
+ })
100
+
101
+ exercise({
102
+ contractId: 'contract-id',
103
+ choiceArgument: { newOwner: 'Bob' },
104
+ })
105
+ ```
106
+
107
+ ### `useStreamContracts(options)`
108
+
109
+ Polling-based live contract updates (5-second interval).
110
+
111
+ ```tsx
112
+ const { contracts, isLoading, error } = useStreamContracts({
113
+ templateId: '#my-pkg:Main:Asset',
114
+ enabled: true, // optional
115
+ })
116
+ ```
117
+
118
+ ### `useCantonClient()`
119
+
120
+ Access the `LedgerClient` directly for advanced use cases.
121
+
122
+ ```tsx
123
+ const client = useCantonClient()
124
+ ```
125
+
126
+ ### `useParty()`
127
+
128
+ Get the current `actAs` party identity.
129
+
130
+ ```tsx
131
+ const party = useParty()
132
+ // 'Alice::1234'
133
+ ```
134
+
135
+ ## Provider
136
+
137
+ Wrap your app with `CantonProvider`. Optionally pass a custom `QueryClient`:
138
+
139
+ ```tsx
140
+ import { QueryClient } from '@tanstack/react-query'
141
+
142
+ const queryClient = new QueryClient({
143
+ defaultOptions: { queries: { staleTime: 10_000 } },
144
+ })
145
+
146
+ <CantonProvider client={ledgerClient} queryClient={queryClient}>
147
+ <App />
148
+ </CantonProvider>
149
+ ```
150
+
151
+ ## Cache Invalidation
152
+
153
+ Mutations automatically invalidate contract queries for the same template:
154
+
155
+ - `useCreateContract` invalidates `['canton', 'contracts', templateId]`
156
+ - `useExercise` invalidates `['canton', 'contracts', templateId]`
157
+
158
+ This means `useContracts` queries refresh automatically after mutations complete.
159
+
160
+ ## Peer Dependencies
161
+
162
+ | Package | Version |
163
+ |---------|---------|
164
+ | `react` | ^18.0.0 \|\| ^19.0.0 |
165
+ | `@tanstack/react-query` | ^5.0.0 |
166
+
167
+ ## Requirements
168
+
169
+ - Node.js >= 18
170
+ - React 18 or 19
171
+
172
+ ## Related
173
+
174
+ - [cantonjs](https://github.com/merged-one/cantonjs) &mdash; Core TypeScript library for Canton
175
+ - [cantonjs-codegen](https://github.com/merged-one/cantonjs/tree/main/packages/cantonjs-codegen) &mdash; DAR-to-TypeScript code generation
176
+
177
+ ## License
178
+
179
+ [Apache-2.0](https://github.com/merged-one/cantonjs/blob/main/LICENSE)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cantonjs-react",
3
- "version": "0.0.1",
3
+ "version": "0.2.0",
4
4
  "description": "React hooks for Canton Network dApps — built on cantonjs",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -35,7 +35,7 @@
35
35
  },
36
36
  "peerDependencies": {
37
37
  "@tanstack/react-query": "^5.0.0",
38
- "cantonjs": "^0.0.1",
38
+ "cantonjs": "^0.2.0",
39
39
  "react": "^18.0.0 || ^19.0.0"
40
40
  },
41
41
  "peerDependenciesMeta": {