qiforge-cli 1.1.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.
- package/License.txt +201 -0
- package/README.md +223 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +145 -0
- package/dist/cli.js.map +1 -0
- package/package.json +79 -0
package/License.txt
ADDED
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
Apache License
|
|
2
|
+
Version 2.0, January 2004
|
|
3
|
+
http://www.apache.org/licenses/
|
|
4
|
+
|
|
5
|
+
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
|
6
|
+
|
|
7
|
+
1. Definitions.
|
|
8
|
+
|
|
9
|
+
"License" shall mean the terms and conditions for use, reproduction,
|
|
10
|
+
and distribution as defined by Sections 1 through 9 of this document.
|
|
11
|
+
|
|
12
|
+
"Licensor" shall mean the copyright owner or entity authorized by
|
|
13
|
+
the copyright owner that is granting the License.
|
|
14
|
+
|
|
15
|
+
"Legal Entity" shall mean the union of the acting entity and all
|
|
16
|
+
other entities that control, are controlled by, or are under common
|
|
17
|
+
control with that entity. For the purposes of this definition,
|
|
18
|
+
"control" means (i) the power, direct or indirect, to cause the
|
|
19
|
+
direction or management of such entity, whether by contract or
|
|
20
|
+
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
|
21
|
+
outstanding shares, or (iii) beneficial ownership of such entity.
|
|
22
|
+
|
|
23
|
+
"You" (or "Your") shall mean an individual or Legal Entity
|
|
24
|
+
exercising permissions granted by this License.
|
|
25
|
+
|
|
26
|
+
"Source" form shall mean the preferred form for making modifications,
|
|
27
|
+
including but not limited to software source code, documentation
|
|
28
|
+
source, and configuration files.
|
|
29
|
+
|
|
30
|
+
"Object" form shall mean any form resulting from mechanical
|
|
31
|
+
transformation or translation of a Source form, including but
|
|
32
|
+
not limited to compiled object code, generated documentation,
|
|
33
|
+
and conversions to other media types.
|
|
34
|
+
|
|
35
|
+
"Work" shall mean the work of authorship, whether in Source or
|
|
36
|
+
Object form, made available under the License, as indicated by a
|
|
37
|
+
copyright notice that is included in or attached to the work
|
|
38
|
+
(an example is provided in the Appendix below).
|
|
39
|
+
|
|
40
|
+
"Derivative Works" shall mean any work, whether in Source or Object
|
|
41
|
+
form, that is based on (or derived from) the Work and for which the
|
|
42
|
+
editorial revisions, annotations, elaborations, or other modifications
|
|
43
|
+
represent, as a whole, an original work of authorship. For the purposes
|
|
44
|
+
of this License, Derivative Works shall not include works that remain
|
|
45
|
+
separable from, or merely link (or bind by name) to the interfaces of,
|
|
46
|
+
the Work and Derivative Works thereof.
|
|
47
|
+
|
|
48
|
+
"Contribution" shall mean any work of authorship, including
|
|
49
|
+
the original version of the Work and any modifications or additions
|
|
50
|
+
to that Work or Derivative Works thereof, that is intentionally
|
|
51
|
+
submitted to Licensor for inclusion in the Work by the copyright owner
|
|
52
|
+
or by an individual or Legal Entity authorized to submit on behalf of
|
|
53
|
+
the copyright owner. For the purposes of this definition, "submitted"
|
|
54
|
+
means any form of electronic, verbal, or written communication sent
|
|
55
|
+
to the Licensor or its representatives, including but not limited to
|
|
56
|
+
communication on electronic mailing lists, source code control systems,
|
|
57
|
+
and issue tracking systems that are managed by, or on behalf of, the
|
|
58
|
+
Licensor for the purpose of discussing and improving the Work, but
|
|
59
|
+
excluding communication that is conspicuously marked or otherwise
|
|
60
|
+
designated in writing by the copyright owner as "Not a Contribution."
|
|
61
|
+
|
|
62
|
+
"Contributor" shall mean Licensor and any individual or Legal Entity
|
|
63
|
+
on behalf of whom a Contribution has been received by Licensor and
|
|
64
|
+
subsequently incorporated within the Work.
|
|
65
|
+
|
|
66
|
+
2. Grant of Copyright License. Subject to the terms and conditions of
|
|
67
|
+
this License, each Contributor hereby grants to You a perpetual,
|
|
68
|
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
69
|
+
copyright license to reproduce, prepare Derivative Works of,
|
|
70
|
+
publicly display, publicly perform, sublicense, and distribute the
|
|
71
|
+
Work and such Derivative Works in Source or Object form.
|
|
72
|
+
|
|
73
|
+
3. Grant of Patent License. Subject to the terms and conditions of
|
|
74
|
+
this License, each Contributor hereby grants to You a perpetual,
|
|
75
|
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
76
|
+
(except as stated in this section) patent license to make, have made,
|
|
77
|
+
use, offer to sell, sell, import, and otherwise transfer the Work,
|
|
78
|
+
where such license applies only to those patent claims licensable
|
|
79
|
+
by such Contributor that are necessarily infringed by their
|
|
80
|
+
Contribution(s) alone or by combination of their Contribution(s)
|
|
81
|
+
with the Work to which such Contribution(s) was submitted. If You
|
|
82
|
+
institute patent litigation against any entity (including a
|
|
83
|
+
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
|
84
|
+
or a Contribution incorporated within the Work constitutes direct
|
|
85
|
+
or contributory patent infringement, then any patent licenses
|
|
86
|
+
granted to You under this License for that Work shall terminate
|
|
87
|
+
as of the date such litigation is filed.
|
|
88
|
+
|
|
89
|
+
4. Redistribution. You may reproduce and distribute copies of the
|
|
90
|
+
Work or Derivative Works thereof in any medium, with or without
|
|
91
|
+
modifications, and in Source or Object form, provided that You
|
|
92
|
+
meet the following conditions:
|
|
93
|
+
|
|
94
|
+
(a) You must give any other recipients of the Work or
|
|
95
|
+
Derivative Works a copy of this License; and
|
|
96
|
+
|
|
97
|
+
(b) You must cause any modified files to carry prominent notices
|
|
98
|
+
stating that You changed the files; and
|
|
99
|
+
|
|
100
|
+
(c) You must retain, in the Source form of any Derivative Works
|
|
101
|
+
that You distribute, all copyright, patent, trademark, and
|
|
102
|
+
attribution notices from the Source form of the Work,
|
|
103
|
+
excluding those notices that do not pertain to any part of
|
|
104
|
+
the Derivative Works; and
|
|
105
|
+
|
|
106
|
+
(d) If the Work includes a "NOTICE" text file as part of its
|
|
107
|
+
distribution, then any Derivative Works that You distribute must
|
|
108
|
+
include a readable copy of the attribution notices contained
|
|
109
|
+
within such NOTICE file, excluding those notices that do not
|
|
110
|
+
pertain to any part of the Derivative Works, in at least one
|
|
111
|
+
of the following places: within a NOTICE text file distributed
|
|
112
|
+
as part of the Derivative Works; within the Source form or
|
|
113
|
+
documentation, if provided along with the Derivative Works; or,
|
|
114
|
+
within a display generated by the Derivative Works, if and
|
|
115
|
+
wherever such third-party notices normally appear. The contents
|
|
116
|
+
of the NOTICE file are for informational purposes only and
|
|
117
|
+
do not modify the License. You may add Your own attribution
|
|
118
|
+
notices within Derivative Works that You distribute, alongside
|
|
119
|
+
or as an addendum to the NOTICE text from the Work, provided
|
|
120
|
+
that such additional attribution notices cannot be construed
|
|
121
|
+
as modifying the License.
|
|
122
|
+
|
|
123
|
+
You may add Your own copyright statement to Your modifications and
|
|
124
|
+
may provide additional or different license terms and conditions
|
|
125
|
+
for use, reproduction, or distribution of Your modifications, or
|
|
126
|
+
for any such Derivative Works as a whole, provided Your use,
|
|
127
|
+
reproduction, and distribution of the Work otherwise complies with
|
|
128
|
+
the conditions stated in this License.
|
|
129
|
+
|
|
130
|
+
5. Submission of Contributions. Unless You explicitly state otherwise,
|
|
131
|
+
any Contribution intentionally submitted for inclusion in the Work
|
|
132
|
+
by You to the Licensor shall be under the terms and conditions of
|
|
133
|
+
this License, without any additional terms or conditions.
|
|
134
|
+
Notwithstanding the above, nothing herein shall supersede or modify
|
|
135
|
+
the terms of any separate license agreement you may have executed
|
|
136
|
+
with Licensor regarding such Contributions.
|
|
137
|
+
|
|
138
|
+
6. Trademarks. This License does not grant permission to use the trade
|
|
139
|
+
names, trademarks, service marks, or product names of the Licensor,
|
|
140
|
+
except as required for reasonable and customary use in describing the
|
|
141
|
+
origin of the Work and reproducing the content of the NOTICE file.
|
|
142
|
+
|
|
143
|
+
7. Disclaimer of Warranty. Unless required by applicable law or
|
|
144
|
+
agreed to in writing, Licensor provides the Work (and each
|
|
145
|
+
Contributor provides its Contributions) on an "AS IS" BASIS,
|
|
146
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
147
|
+
implied, including, without limitation, any warranties or conditions
|
|
148
|
+
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
|
149
|
+
PARTICULAR PURPOSE. You are solely responsible for determining the
|
|
150
|
+
appropriateness of using or redistributing the Work and assume any
|
|
151
|
+
risks associated with Your exercise of permissions under this License.
|
|
152
|
+
|
|
153
|
+
8. Limitation of Liability. In no event and under no legal theory,
|
|
154
|
+
whether in tort (including negligence), contract, or otherwise,
|
|
155
|
+
unless required by applicable law (such as deliberate and grossly
|
|
156
|
+
negligent acts) or agreed to in writing, shall any Contributor be
|
|
157
|
+
liable to You for damages, including any direct, indirect, special,
|
|
158
|
+
incidental, or consequential damages of any character arising as a
|
|
159
|
+
result of this License or out of the use or inability to use the
|
|
160
|
+
Work (including but not limited to damages for loss of goodwill,
|
|
161
|
+
work stoppage, computer failure or malfunction, or any and all
|
|
162
|
+
other commercial damages or losses), even if such Contributor
|
|
163
|
+
has been advised of the possibility of such damages.
|
|
164
|
+
|
|
165
|
+
9. Accepting Warranty or Additional Liability. While redistributing
|
|
166
|
+
the Work or Derivative Works thereof, You may choose to offer,
|
|
167
|
+
and charge a fee for, acceptance of support, warranty, indemnity,
|
|
168
|
+
or other liability obligations and/or rights consistent with this
|
|
169
|
+
License. However, in accepting such obligations, You may act only
|
|
170
|
+
on Your own behalf and on Your sole responsibility, not on behalf
|
|
171
|
+
of any other Contributor, and only if You agree to indemnify,
|
|
172
|
+
defend, and hold each Contributor harmless for any liability
|
|
173
|
+
incurred by, or claims asserted against, such Contributor by reason
|
|
174
|
+
of your accepting any such warranty or additional liability.
|
|
175
|
+
|
|
176
|
+
END OF TERMS AND CONDITIONS
|
|
177
|
+
|
|
178
|
+
APPENDIX: How to apply the Apache License to your work.
|
|
179
|
+
|
|
180
|
+
To apply the Apache License to your work, attach the following
|
|
181
|
+
boilerplate notice, with the fields enclosed by brackets "[]"
|
|
182
|
+
replaced with your own identifying information. (Don't include
|
|
183
|
+
the brackets!) The text should be enclosed in the appropriate
|
|
184
|
+
comment syntax for the file format. We also recommend that a
|
|
185
|
+
file or class name and description of purpose be included on the
|
|
186
|
+
same "printed page" as the copyright notice for easier
|
|
187
|
+
identification within third-party archives.
|
|
188
|
+
|
|
189
|
+
Copyright 2025 IXO World
|
|
190
|
+
|
|
191
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
192
|
+
you may not use this file except in compliance with the License.
|
|
193
|
+
You may obtain a copy of the License at
|
|
194
|
+
|
|
195
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
196
|
+
|
|
197
|
+
Unless required by applicable law or agreed to in writing, software
|
|
198
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
199
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
200
|
+
See the License for the specific language governing permissions and
|
|
201
|
+
limitations under the License.
|
package/README.md
ADDED
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
# IXO Oracles CLI
|
|
2
|
+
|
|
3
|
+
A command-line interface for creating and managing IXO Oracle projects. This CLI helps you set up AI Agent oracles built with LangGraph, using Matrix as a datastore with linked resources stored on the IXO blockchain.
|
|
4
|
+
|
|
5
|
+
## What is IXO Oracles CLI?
|
|
6
|
+
|
|
7
|
+
The IXO Oracles CLI automates the complete setup of AI Agent oracle projects. It handles:
|
|
8
|
+
|
|
9
|
+
- **Blockchain Integration**: Creates entities on the IXO blockchain with linked resources stored in Matrix
|
|
10
|
+
- **Matrix Account Creation**: Sets up Matrix accounts for data storage and communication
|
|
11
|
+
- **Project Initialization**: Clones the [IXO Oracles boilerplate](https://github.com/ixoworld/qiforge) and configures the environment
|
|
12
|
+
- **Authentication**: Integrates with SignX for secure blockchain operations
|
|
13
|
+
|
|
14
|
+
## Prerequisites
|
|
15
|
+
|
|
16
|
+
- Node.js 22+
|
|
17
|
+
- IXO Mobile App (for SignX authentication)
|
|
18
|
+
|
|
19
|
+
## Installation
|
|
20
|
+
|
|
21
|
+
Install the CLI globally using npm:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
npm install -g ixo-oracles-cli
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Or with pnpm:
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
pnpm add -g ixo-oracles-cli
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
**Important for pnpm users:** After installation, you need to approve build scripts:
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
pnpm approve-builds -g
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
When prompted, select `protobufjs` and approve it:
|
|
40
|
+
|
|
41
|
+
```
|
|
42
|
+
✔ Choose which packages to build · protobufjs
|
|
43
|
+
✔ The next packages will now be built: protobufjs.
|
|
44
|
+
Do you approve? (y/N) · true
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Or with yarn:
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
yarn global add ixo-oracles-cli
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Quick Start
|
|
54
|
+
|
|
55
|
+
1. **Initialize a new oracle project:**
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
oracles-cli --init
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
2. **Or run the interactive CLI:**
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
oracles-cli
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
3. **Follow the prompts:**
|
|
68
|
+
- First-time users will need to login with SignX (keep your IXO Mobile App open)
|
|
69
|
+
- Enter your project name
|
|
70
|
+
- Select the template (IXO Oracles boilerplate or custom)
|
|
71
|
+
- Configure your oracle details
|
|
72
|
+
|
|
73
|
+
## Commands
|
|
74
|
+
|
|
75
|
+
### `oracles-cli --init` - Initialize Project
|
|
76
|
+
|
|
77
|
+
Creates a new IXO Oracle project with all necessary components:
|
|
78
|
+
|
|
79
|
+
- **Project Setup**: Creates directory and clones the IXO Oracles boilerplate
|
|
80
|
+
- **Entity Creation**: Creates a blockchain entity with linked resources stored in Matrix
|
|
81
|
+
- **Matrix Account**: Sets up Matrix account for data storage
|
|
82
|
+
- **Environment Configuration**: Creates `.env` file with all necessary variables
|
|
83
|
+
|
|
84
|
+
### `oracles-cli` - Interactive Menu
|
|
85
|
+
|
|
86
|
+
Launches an interactive menu with the following options:
|
|
87
|
+
|
|
88
|
+
- **init** - Initialize a new project
|
|
89
|
+
- **create-entity** - Create a blockchain entity
|
|
90
|
+
- **logout** - Sign out
|
|
91
|
+
|
|
92
|
+
### Other Commands
|
|
93
|
+
|
|
94
|
+
- **create-entity** - Create an entity with oracle profile, linked resources, and metadata
|
|
95
|
+
- **logout** - Clear your authentication session
|
|
96
|
+
- **help** - Show help information and available commands
|
|
97
|
+
|
|
98
|
+
## Project Structure
|
|
99
|
+
|
|
100
|
+
After initialization, your project will have:
|
|
101
|
+
|
|
102
|
+
```
|
|
103
|
+
your-oracle-project/
|
|
104
|
+
├── apps/
|
|
105
|
+
│ └── app/
|
|
106
|
+
│ ├── .env # Environment configuration
|
|
107
|
+
│ └── ... # Application files
|
|
108
|
+
├── packages/ # Shared packages
|
|
109
|
+
└── ... # Other project files
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
## Environment Configuration
|
|
113
|
+
|
|
114
|
+
The CLI automatically creates a `.env` file with:
|
|
115
|
+
|
|
116
|
+
```env
|
|
117
|
+
PORT=4000
|
|
118
|
+
ORACLE_NAME=your-oracle-name
|
|
119
|
+
|
|
120
|
+
# Matrix Configuration
|
|
121
|
+
MATRIX_BASE_URL=https://matrix.ixo.world
|
|
122
|
+
MATRIX_ORACLE_ADMIN_ACCESS_TOKEN=your-access-token
|
|
123
|
+
MATRIX_ORACLE_ADMIN_PASSWORD=your-password
|
|
124
|
+
MATRIX_ORACLE_ADMIN_USER_ID=your-user-id
|
|
125
|
+
|
|
126
|
+
# AI/ML Services (configure as needed)
|
|
127
|
+
OPENAI_API_KEY=
|
|
128
|
+
LANGFUSE_PUBLIC_KEY=
|
|
129
|
+
LANGFUSE_SECRET_KEY=
|
|
130
|
+
LANGFUSE_HOST=https://cloud.langfuse.com
|
|
131
|
+
OPEN_ROUTER_API_KEY=
|
|
132
|
+
|
|
133
|
+
# Blockchain Details (store securely)
|
|
134
|
+
ORACLE_ADDRESS=your-address
|
|
135
|
+
ORACLE_DID=your-did
|
|
136
|
+
ORACLE_MNEMONIC=your-mnemonic
|
|
137
|
+
MATRIX_VAULT_PIN=your-pin
|
|
138
|
+
ENTITY_DID=your-entity-did
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
## Authentication
|
|
142
|
+
|
|
143
|
+
The CLI uses SignX for authentication:
|
|
144
|
+
|
|
145
|
+
1. Keep your IXO Mobile App open during the login process
|
|
146
|
+
2. Follow the QR code or manual authentication prompts
|
|
147
|
+
3. Your credentials are securely stored locally for future use
|
|
148
|
+
|
|
149
|
+
## Next Steps
|
|
150
|
+
|
|
151
|
+
After project initialization:
|
|
152
|
+
|
|
153
|
+
1. **Navigate to your project:**
|
|
154
|
+
|
|
155
|
+
```bash
|
|
156
|
+
cd your-project-name
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
2. **Install dependencies:**
|
|
160
|
+
|
|
161
|
+
```bash
|
|
162
|
+
pnpm install
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
3. **Build the project:**
|
|
166
|
+
|
|
167
|
+
```bash
|
|
168
|
+
pnpm build
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
4. **Start development:**
|
|
172
|
+
```bash
|
|
173
|
+
cd apps/app
|
|
174
|
+
pnpm start:dev
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
## Development (Contributing to CLI)
|
|
178
|
+
|
|
179
|
+
If you want to contribute to the CLI itself:
|
|
180
|
+
|
|
181
|
+
1. **Clone the repository:**
|
|
182
|
+
|
|
183
|
+
```bash
|
|
184
|
+
git clone https://github.com/ixoworld/ixo-oracles-cli
|
|
185
|
+
cd ixo-oracles-cli
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
2. **Install dependencies:**
|
|
189
|
+
|
|
190
|
+
```bash
|
|
191
|
+
pnpm install
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
3. **Build the CLI:**
|
|
195
|
+
|
|
196
|
+
```bash
|
|
197
|
+
pnpm build
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
4. **Run locally:**
|
|
201
|
+
```bash
|
|
202
|
+
pnpm start
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
**Development Scripts:**
|
|
206
|
+
|
|
207
|
+
- `pnpm build` - Build the CLI
|
|
208
|
+
- `pnpm dev` - Watch mode for development
|
|
209
|
+
- `pnpm test` - Run tests
|
|
210
|
+
- `pnpm lint` - Lint code
|
|
211
|
+
- `pnpm type-check` - Type check
|
|
212
|
+
|
|
213
|
+
## Support
|
|
214
|
+
|
|
215
|
+
For issues and questions:
|
|
216
|
+
|
|
217
|
+
- Create an issue in the repository
|
|
218
|
+
- Join the IXO Discord community
|
|
219
|
+
- Check the IXO documentation
|
|
220
|
+
|
|
221
|
+
## License
|
|
222
|
+
|
|
223
|
+
This project is licensed under the Apache License 2.0. See [License.txt](License.txt) for details.
|
package/dist/cli.d.ts
ADDED
package/dist/cli.js
ADDED
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import{cancel as De,intro as br,isCancel as Ct,log as G,outro as Pr,select as Rt,spinner as Nr}from"@clack/prompts";import M from"process";var z=class{commands;constructor(){this.commands=new Map}register(e){this.commands.set(e.name,e)}get(e){return this.commands.get(e)}getAll(){return Array.from(this.commands.values())}getCommandOptions(){return this.getAll().map(e=>({value:e.name,label:e.name,hint:e.description}))}};import*as w from"@clack/prompts";import{select as bt}from"@clack/prompts";import{z as D}from"zod";var S=async r=>{let e=await bt({message:"Select network: (default: devnet)",options:[{value:"mainnet",label:"Mainnet"},{value:"testnet",label:"Testnet"},{value:"devnet",label:"Devnet"}],initialValue:"devnet",maxItems:1});return r.addValue("network",e),e},$e={mainnet:"did:ixo:entity:2f22535f8b179a51d77a0e302e68d35d",testnet:"did:ixo:entity:3d079ebc0b332aad3305bb4a51c72edb",devnet:"did:ixo:entity:2f22535f8b179a51d77a0e302e68d35d"},L={devnet:"https://devmx.ixo.earth",testnet:"https://testmx.ixo.earth",mainnet:"https://mx.ixo.earth"};var We={devnet:"https://ixo-portal.vercel.app",testnet:"https://ixo-portal.vercel.app",mainnet:"https://ixo-portal.vercel.app"},N={mainnet:"https://impacthub.ixo.world/rpc/",testnet:"https://testnet.ixo.earth/rpc/",devnet:"https://devnet.ixo.earth/rpc/"},B={devnet:"https://domain-indexer.devnet.ixo.earth/index",testnet:"https://domain-indexer.testnet.ixo.earth/index",mainnet:"https://domain-indexer.ixo.earth/index"},j={devnet:"https://devnet-blocksync-graphql.ixo.earth/graphql",testnet:"https://testnet-blocksync-graphql.ixo.earth/graphql",mainnet:"https://blocksync-graphql.ixo.earth/graphql"},ve={devnet:"https://mcp-memory-engine.devnet.ixo.earth/",testnet:"https://memory-engine.testnet.ixo.earth/",mainnet:"https://memory-engine.ixo.earth/"},Ce={devnet:"https://mcp-memory-engine.devnet.ixo.earth/",testnet:"https://mcp-memory-engine.testnet.ixo.earth/",mainnet:"https://mcp-memory-engine.ixo.earth/"},Re={devnet:"https://ai-sandbox-devnet.ixo.earth/mcp",testnet:"https://ai-sandbox-testnet.ixo.earth/mcp",mainnet:"https://ai-sandbox.ixo.earth/mcp"},Ee={devnet:"https://subscriptions-api.ixo-api.workers.dev",testnet:"https://subscriptions-api-testnet.ixo-api.workers.dev/",mainnet:"https://subscriptions-api-mainnet.ixo-api.workers.dev/"},T=(r,e="This field is required")=>{let i=D.string().min(1,e).safeParse(r);if(!i.success)return i.error.message},F=r=>{let t=D.string().regex(/^did:ixo:entity:[a-f0-9]{32}$/,"Invalid entity DID").safeParse(r);if(!t.success)return t.error.message},_=(r,e="This url is required or a valid URL")=>{let i=D.url(e).safeParse(r);if(!i.success)return i.error.message},Xe=(r,e="This number is required")=>{let i=D.number().min(1,e).safeParse(r);if(!i.success)return i.error.message},J=r=>{let t=D.string().min(1,"PIN is required").refine(i=>/^\d{6}$/.test(i),"PIN must be exactly 6 digits").safeParse(r);if(!t.success)return t.error.issues[0]?.message??"Invalid PIN"},Q=r=>{let t=D.string().min(1,"Matrix homeserver URL is required").refine(i=>/^https?:\/\//.test(i),"Must start with http:// or https://").refine(i=>!i.endsWith("/"),"Must not end with a trailing slash").safeParse(r);if(!t.success)return t.error.issues[0]?.message??"Invalid Matrix URL"};function Ke(r){let e=new URL(r),t=e.hostname,i=e.protocol;return{homeServerUrl:r,roomBotUrl:`${i}//rooms.bot.${t}`,stateBotUrl:`${i}//state.bot.${t}`,bidsBotUrl:`${i}//bids.bot.${t}`,claimsBotUrl:`${i}//claims.bot.${t}`}}import{isCancel as lr,log as h,spinner as dr,text as mr}from"@clack/prompts";import{customMessages as ft,ixo as x,utils as Oe}from"@ixo/impactxclient-sdk";import{sha256 as jt}from"@cosmjs/crypto";import{encrypt as Ft}from"eciesjs";import{ClientEvent as Vt,createClient as be}from"matrix-js-sdk";import qt from"md5";var Z=new Map;function Pt(r){return Z.get(r)instanceof Uint8Array}function Nt(r){return Z.get(r)}function Se(){Z.clear()}async function Be({keys:r}){let e=Object.keys(r),t=e.find(Pt);if(console.info("[] getSecretStorageKey",r,e,t),!t)return null;let i=Nt(t);return[t,i]}function je(r,e,t){Z.set(r,t)}import{Bip39 as He,EnglishMnemonic as Ge,Secp256k1 as Ae,sha256 as Ut,Slip10 as Ye,Slip10Curve as ze,stringToPath as Je}from"@cosmjs/crypto";import{DirectSecp256k1HdWallet as kt}from"@cosmjs/proto-signing";import{createQueryClient as Qe,createSigningClient as Mt,customMessages as Dt,ixo as Lt,utils as _t}from"@ixo/impactxclient-sdk";import{createCipheriv as $t,randomBytes as Wt}from"crypto";import{createRegistry as Tt,utils as Ot}from"@ixo/impactxclient-sdk";function V(r){try{return Ot.proto.fromTimestamp(r).getTime()}catch{return}}var ee={BasicAllowance:"/cosmos.feegrant.v1beta1.BasicAllowance",PeriodicAllowance:"/cosmos.feegrant.v1beta1.PeriodicAllowance"},Fe=r=>{let e=Tt();return(r??[]).map(t=>{let i=t.allowance,n=e.decode(i);switch(i.typeUrl){case ee.BasicAllowance:return{granter:t.granter,grantee:t.grantee,type:ee.BasicAllowance,expiration:n.expiration?V(n.expiration):null,limit:n.spendLimit?.length?n.spendLimit.find(o=>o.denom==="uixo")?.amount:null,msgs:[]};case ee.PeriodicAllowance:return{granter:t.granter,grantee:t.grantee,type:ee.PeriodicAllowance,expiration:n.basic?.expiration?V(n.basic.expiration):null,limit:n?.periodCanSpend?n?.periodCanSpend?.find(o=>o.denom==="uixo")?.amount:n?.basic?.spendLimit?.length?n?.basic?.spendLimit?.find(o=>o.denom==="uixo")?.amount:null,msgs:[]};default:return{type:i.typeUrl,granter:t.granter,grantee:t.grantee,expiration:n.expiration?V(n.expiration):n.basic?.expiration?V(n.basic.expiration):null,limit:n.spendLimit?.length?n.spendLimit.find(o=>o.denom==="uixo")?.amount:n?.periodCanSpend?n?.periodCanSpend?.find(o=>o.denom==="uixo")?.amount:n?.basic?.spendLimit?.length?n?.basic?.spendLimit?.find(o=>o.denom==="uixo")?.amount:null,msgs:n.allowedMessages}}})},Ve=r=>{if(r==null)return!1;let e=typeof r=="object"?V(r):r;return e==null?!0:e<Date.now()},qe=r=>r==null?!1:(typeof r=="object"?Number(r?.amount??0):typeof r=="string"?Number(r??0):r)<=5e-4;async function Ie(r,e){if(!e)throw new Error("Network parameter is required but was undefined");console.log(`\u{1F50D} Checking IID document for DID: ${r} on network: ${e}`);let t=N[e];if(!t)throw new Error(`Invalid network: ${e}. Valid networks are: ${Object.keys(N).join(", ")}`);console.log(`\u{1F517} Using RPC URL: ${t}`);try{return!!(await(await Qe(t)).ixo.iid.v1beta1.iidDocument({id:r}))?.iidDocument?.id}catch(i){if(i.message?.includes("did document not found")||i.message?.includes("(22)"))return!1;throw console.error("Error checking IID document:",i),i}}async function Ze(r,e,t,i){try{let n=await t.getAccounts(),{address:o,pubkey:s}=n[0]??{},c=await Xt(o,e),a=c?.length?Fe(c)?.find(d=>!!d&&!Ve(d.expiration)&&!qe(d.limit))?.granter:void 0,l={typeUrl:"/ixo.iid.v1beta1.MsgCreateIidDocument",value:Lt.iid.v1beta1.MsgCreateIidDocument.fromPartial({id:r,verifications:Dt.iid.createIidVerificationMethods({did:r,pubkey:s,address:o,controller:r,type:"secp"}),signer:o,controllers:[r],...i?.length?{services:i}:{}})};await Kt({offlineSigner:t,messages:[l],feegrantGranter:a,network:e})}catch(n){throw console.error(n),n}}async function Xt(r,e){try{let t=N[e];if(!t)throw new Error(`Invalid network: ${e}`);return(await(await Qe(t)).cosmos.feegrant.v1beta1.allowances({grantee:r}))?.allowances??[]}catch(t){console.error("queryAddressAllowances::",t.message);return}}var Kt=async({offlineSigner:r,messages:e,memo:t="Signing with Mnemonic Demo",feegrantGranter:i,network:n})=>{let o=N[n];if(!o)throw new Error(`Invalid network: ${n}`);let s=await Mt(o,r),c=await r.getAccounts(),{address:a}=c[0]??{},l=await s.simulate(a,e,t),m=(l>5e4?l:(e??[]).length*5e5)*1.7,p=Bt(m),v={amount:[{denom:"uixo",amount:String(Math.round(p.average))}],gas:String(Math.round(m)),granter:i},y=await s.signAndBroadcast(a,e,v,t,void 0);if(!!y.code)throw new Error(`Error when broadcasting tx ${y.transactionHash} at height ${y.height}. Code: ${y.code}; Raw log: ${y.rawLog}`)},Bt=r=>{let e={low:.02,average:.035,high:.045},t=r<.01?.01:r;return{low:t*e.low,average:t*e.average,high:t*e.high}},te=r=>new Promise(e=>setTimeout(e,r));function et(r,e){let t=Wt(16),i=$t("aes-256-cbc",Buffer.from(e.padEnd(32)),t),n=i.update(r);return n=Buffer.concat([n,i.final()]),t.toString("hex")+":"+n.toString("hex")}var tt=async r=>{let e=await kt.fromMnemonic(r,{prefix:"ixo"}),t=(await e.getAccounts())[0],i=await He.mnemonicToSeed(new Ge(r)),n=Je("m/44'/118'/0'/0/0"),s=Ye.derivePath(ze.Secp256k1,i,n).privkey,c=await Ae.makeKeypair(s),a=Ae.compressPubkey(c.pubkey);return{mnemonic:r,did:_t.did.generateSecpDid(t.address),baseAccount:t,async getAccounts(){return await e.getAccounts()},async signDirect(d,m){return await e.signDirect(d,m)},async sign(d){try{let m=await He.mnemonicToSeed(new Ge(r)),p=Je("m/44'/118'/0'/0/0"),{privkey:v}=Ye.derivePath(ze.Secp256k1,m,p),y=new Uint8Array(Buffer.from(d,"base64")),P=Ut(y);return(await Ae.createSignature(P,v)).toFixedLength().slice(0,64)}catch(m){throw console.error("Error during signature creation:",m),m}}}};var Ht="/.well-known/matrix/client",Pe=async({homeServerUrl:r,username:e,password:t,deviceName:i},n=!1)=>{let o=r,s=e,c=s.match(/^@(.+):(.+\..+)$/);c&&(s=c[1],o=c[2],o=n?o:await er(o));try{let a=nt(o),l=await a.login("m.login.password",{identifier:{type:"m.id.user",user:tr(s)},password:t,initial_device_display_name:i});return{accessToken:l.access_token,deviceId:l.device_id,userId:l.user_id,baseUrl:n?o:l?.well_known?.["m.homeserver"]?.base_url||a.baseUrl}}catch(a){let l=a.message;throw l==="Unknown message"&&(l="Please check your credentials"),console.error("mxLogin::",l),new Error(l)}};async function Gt(r){let e=await fetch(`${r}/public-key`,{method:"GET",headers:{"Content-Type":"application/json"}});if(!e.ok)throw new Error("Failed to fetch public key for encryption");return await e.json()}function Yt(r){let e={timestamp:new Date().toISOString(),address:r,service:"matrix",type:"create-account"},t=Buffer.from(JSON.stringify(e)).toString("base64");return{challenge:e,challengeBase64:t}}function zt(r,e){let t=new Uint8Array(Buffer.from(e,"hex")),i=new Uint8Array(Buffer.from(r,"utf8")),n=Ft(t,i);return Array.from(n,o=>o.toString(16).padStart(2,"0")).join("")}async function Jt(r,e,t,i,n,o){let s=await Gt(o),c=zt(e,s.publicKey),a={address:r,encryptedPassword:c,publicKeyFingerprint:s.fingerprint,secpResult:{signature:t,challenge:i}},l=await fetch(`${o}/user/create`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(a)});if(!l.ok){let d=await l.text(),m=`Failed to create user account (HTTP ${l.status})`;try{let p=JSON.parse(d);m=p.error||p.message||p.detail||d}catch{m=d||m}throw console.error(`Room bot error [${l.status}]: ${d}`),new Error(m)}return await l.json()}async function rt(r,e,t,i,n,o){try{let{challengeBase64:s}=Yt(r),c=await i.sign(s),a=Buffer.from(c).toString("base64");if(!(await Jt(r,e,a,s,n,o)).success)throw new Error("Failed to create matrix account via API");let d=Ne(r);return await Pe({homeServerUrl:n,username:d,password:e,deviceName:t})}catch(s){throw console.error("mxRegisterWithSecp error:",s),s}}async function it({homeServerUrl:r,username:e}){let t=nt(r);try{return!!await t.isUsernameAvailable(e)}catch{return!1}}function nt(r){if(!r)throw new Error("Home server URL is required to instantiate matrix client");return be({baseUrl:r})}async function ot({homeServerUrl:r,accessToken:e,userId:t,deviceId:i}){if(console.log("createMatrixClient::",{homeServerUrl:r,accessToken:e,userId:t,deviceId:i}),!r||!e||!t||!i)throw new Error("Login to Matrix account before trying to instantiate Matrix client.");let n=be({baseUrl:r,accessToken:e,userId:t,deviceId:i,timelineSupport:!0,cryptoCallbacks:{getSecretStorageKey:Be,cacheSecretStorageKey:je},verificationMethods:["m.sas.v1"]});return await n.initRustCrypto({useIndexedDB:!1}),n.setMaxListeners(20),await n.startClient({lazyLoadMembers:!0,includeArchivedRooms:!1}),await new Promise((o,s)=>{let c={NULL:()=>{console.info("[NULL] state")},SYNCING:()=>{},PREPARED:()=>{console.info(`[PREPARED] state: user ${t}`),o()},RECONNECTING:()=>{console.info("[RECONNECTING] state")},CATCHUP:()=>{console.info("[CATCHUP] state")},ERROR:()=>{s(new Error("[ERROR] state: starting matrix client"))},STOPPED:()=>{console.info("[STOPPED] state")}};n.on(Vt.Sync,a=>{c[a]()})}),n}async function re({mxClient:r,baseUrl:e,accessToken:t,userId:i,deviceId:n}){let o=r;o||(o=be({baseUrl:e,accessToken:t,userId:i,deviceId:n})),o&&(o.stopClient(),await o.logout().catch(console.error),o.clearStores())}function st(r){let e=r.getAccountData("m.cross_signing.master");return console.log("hasCrossSigningAccountData::masterKeyData",e),!!e}async function at(r,{securityPhrase:e,password:t,forceReset:i=!1,skipBootstrapSecureStorage:n=!1}){i&&Se();let o=r.getCrypto();if(!o)throw new Error("Failed to setup matrix cross signing - failed to get matrix crypto api");if(!n){let c=await o.createRecoveryKeyFromPassphrase(e);Se(),await o.bootstrapSecretStorage({createSecretStorageKey:async()=>c,setupNewSecretStorage:i})}let s=r.getUserId();return await o.bootstrapCrossSigning({authUploadDeviceSigningKeys:async function(c){await c(rr({userId:s,password:t}))},setupNewCrossSigning:i}),await o.resetKeyBackup(),await te(300),!!r.getAccountData("m.cross_signing.master")}function Ne(r){if(!r)throw new Error("Address is required to generate matrix username");return"did-ixo-"+r}function ct(r){return Buffer.from(qt(r.replace(/ /g,""))).toString("base64").slice(0,24)}function lt(r){let e=jt(new TextEncoder().encode(r.replace(/ /g,"")));return Buffer.from(e).toString("base64").slice(0,32)}function Qt(r){return r.replace(/^(https?:\/\/)/,"").replace(/\/$/,"")}function Zt(r,e=""){return"did-ixo-"+r+e}function dt(r,e){return"#"+Zt(r)+":"+Qt(e)}async function er(r){let e="https://";/^https?:\/\//.test(r)&&(e="");let t=`${e}${r}${Ht}`;try{let o=(await(await fetch(t,{method:"GET"})).json())["m.homeserver"]?.base_url;if(o===void 0)throw new Error;return o}catch{return`${e}${r}`}}function tr(r){return(r.indexOf("@")===0?r.substring(1):r).trim()}function rr({userId:r,password:e}){return{type:"m.login.password",password:e,identifier:{type:"m.id.user",user:r}}}import{ixo as ir,utils as Te}from"@ixo/impactxclient-sdk";import{createMatrixApiClient as nr}from"@ixo/matrixclient-sdk";var mt="Oracles CLI";async function ie({pin:r,oracleName:e,network:t,oracleAvatarUrl:i,matrixHomeServerUrl:n},o){try{let{homeServerUrl:s,roomBotUrl:c}=Ke(n),a=Te.mnemonic.generateMnemonic(),l=await tt(a),d=l.baseAccount.address;console.log("\u2705 Wallet created:",d),await o(d);let m=Te.did.generateSecpDid(d),p=await Ie(m,t);if(console.log("\u2705 DID exists:",p),!p){console.log("\u2705 DID does not exist, creating...");let U=ir.iid.v1beta1.Service.fromPartial({id:`${m}#matrix`,type:"MatrixHomeServer",serviceEndpoint:s});if(await Ze(m,t,l,[U]),console.log("\u2705 DID created, waiting 500ms..."),await te(500),console.log("\u2705 Checking if DID exists..."),!await Ie(m,t))throw new Error("Failed to create DID document")}console.log("\u2705 DID created:",m);let v=Te.mnemonic.generateMnemonic(12),y=Ne(d),P=ct(v),he=lt(v);if(!await it({homeServerUrl:s,username:y}))throw new Error("Matrix account already exists");let R=await rt(d,P,mt,l,s,c);if(!R?.accessToken)throw new Error("Failed to register matrix account");console.log("\u2705 Matrix account created:",R.userId);let K=await ot({homeServerUrl:s,accessToken:R.accessToken,userId:R.userId,deviceId:R.deviceId});try{await Promise.all([K.setDisplayName(e),K.setAvatarUrl(i)])}catch(U){console.error("Failed to set display name or avatar url:",U)}let Y=nr({homeServerUrl:s,accessToken:R.accessToken}),we=st(K);if(!we&&(we=await at(K,{securityPhrase:he,password:P,forceReset:!0}),!we))throw new Error("Failed to setup cross signing");console.log("\u2705 Matrix cross-signing setup completed");let St=dt(d,R.baseUrl),A=(await Y.room.v1beta1.queryId(St).catch(()=>{}))?.room_id??"";if(!A){let U=await fetch(`${c}/room/source`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({did:m,userMatrixId:R.userId})});if(!U.ok)throw new Error("Failed to create matrix room");if(A=(await U.json()).roomId,!A)throw new Error("Failed to create user matrix room")}let ye=await Y.room.v1beta1.listJoinedMembers(A).catch(()=>{}),xe=!!ye?.joined?.[R.userId];if(!xe){if(!(await Y.room.v1beta1.join(A)).room_id)throw new Error("Failed to join matrix room");if(ye=await Y.room.v1beta1.listJoinedMembers(A),xe=!!ye?.joined?.[R.userId],!xe)throw new Error("Failed to join matrix room")}console.log("\u2705 Matrix room created/joined:",A);let At=et(v,r),_e=await fetch(`${s}/_matrix/client/v3/rooms/${A}/state/ixo.room.state.secure/encrypted_mnemonic`,{method:"PUT",headers:{"Content-Type":"application/json",Authorization:`Bearer ${R.accessToken}`},body:JSON.stringify({encrypted_mnemonic:At})});if(!_e.ok)throw new Error("Failed to store encrypted mnemonic in matrix room");return await _e.json(),console.log("\u2705 Encrypted Matrix mnemonic stored in room"),K.stopClient(),{address:d,did:m,mnemonic:a,matrixUserId:R.userId,matrixRoomId:A,matrixMnemonic:v,matrixPassword:P,matrixAccessToken:R.accessToken,matrixRecoveryPhrase:he,matrixHomeServerUrl:s,pin:r,matrixDeviceName:mt}}catch(s){throw console.error("Simplified registration failed:",s),s}}import{createMatrixApiClient as ar,utils as cr}from"@ixo/matrixclient-sdk";import{CID as or}from"multiformats";import{base64 as sr}from"multiformats/bases/base64";import*as pt from"multiformats/hashes/sha2";async function gt(r){let e=r.startsWith("m")?r:"m"+r,t=sr.decode(e),i=await pt.sha256.digest(t);return or.create(1,85,i).toString()}function ut(r){let e=new TextEncoder().encode(r);return btoa(String.fromCharCode(...Array.from(e)))}var q=async({data:r,fileName:e,homeServerUrl:t,accessToken:i})=>{let n=ar({homeServerUrl:t,accessToken:i}),o=JSON.stringify(r),s=Buffer.from(o,"utf8"),c=e+".json",l=await n.media.v1beta1.upload(c,"application/ld+json",s),d=cr.mxc.mxcUrlToHttp(t,l.content_uri);if(!d)throw new Error("Failed to upload file to Matrix");let m=JSON.stringify(r),p=ut(m),v=await gt(p);return{encrypted:"false",cid:v,proof:v,serviceEndpoint:d,mxc:l.content_uri}};var O=class{constructor(e,t){this.config=t;if(!e.did||!e.pubKey||!e.address||!e.algo)throw new Error("Wallet not found");this.wallet=e}wallet;buildMsgCreateEntity(e){return{typeUrl:"/ixo.entity.v1beta1.MsgCreateEntity",value:x.entity.v1beta1.MsgCreateEntity.fromPartial({entityType:"oracle",context:[],entityStatus:0,verification:[...ft.iid.createIidVerificationMethods({did:this.wallet.did,pubkey:new Uint8Array(Buffer.from(this.wallet.pubKey)),address:this.wallet.address,controller:this.wallet.did,type:this.wallet.algo==="ed25519"?"ed":"secp"})],controller:[this.wallet.did],ownerAddress:this.wallet.address,ownerDid:this.wallet.did,relayerNode:$e[this.config.getValue("network")??"devnet"],service:[x.iid.v1beta1.Service.fromPartial({id:"{id}#matrix",type:"MatrixHomeServer",serviceEndpoint:e})],linkedResource:[],accordedRight:[],linkedEntity:[],linkedClaim:[],startDate:Oe.proto.toTimestamp(new Date),endDate:Oe.proto.toTimestamp(new Date(Date.now()+31536e8))})}}addLinkedAccounts(e,{oracleAccountAddress:t}){if(!this.wallet.signXClient||!this.wallet.wallet)throw new Error("SignX client or wallet not found");let o=[{devnet:"did:ixo:ixo17w9u5uk4qjyjgeyqfpnp92jwy58faey9vvp3ar",testnet:"did:ixo:ixo14vjrckltpngugp03tcasfgh5qakey9n3sgm6y2",mainnet:"did:ixo:ixo1d39eutxdc0e8mnp0fmzqjdy6aaf26s9hzrk33r"}[this.config.getValue("network")],`did:ixo:${t}`].map(s=>x.iid.v1beta1.LinkedEntity.fromPartial({id:s,type:"agent",relationship:"admin",service:"matrix"}));e.value.linkedEntity=o}async createAuthZConfig({oracleAccountAddress:e,oracleName:t,entityDid:i,homeServerUrl:n,accessToken:o}){let c=await q({data:{"@context":["https://schema.org",{ixo:"https://w3id.org/ixo/context/v1",oracle:{"@id":i,"@type":"@id"}}],"@type":"Service","@id":"oracle:OracleAuthorization",name:"OracleAuthorization",description:"OracleAuthorization",serviceType:"OracleClaimAuthorizationService",requiredPermissions:["/ixo.claims.v1beta1.MsgCreateClaimAuthorization"],granteeAddress:e,granterAddress:"",oracleName:t},fileName:"authz",homeServerUrl:n,accessToken:o});return x.iid.v1beta1.LinkedResource.fromPartial({id:"{id}#orz",type:"oracleAuthZConfig",proof:c.proof,right:"",encrypted:"false",mediaType:"application/json",description:"Orale AuthZ Config",serviceEndpoint:c.serviceEndpoint})}async createFeesConfig({entityDid:e,price:t,denom:i,homeServerUrl:n,accessToken:o}){let s={"@context":["https://schema.org",{ixo:"https://w3id.org/ixo/context/v1",oracle:{"@id":e,"@type":"@id"}}],"@type":"Service","@id":"oracle:ServiceFeeModel",name:"Pricing",description:"Pricing",serviceType:"",offers:{"@type":"Offer",priceCurrency:i,priceSpecification:{"@type":"PaymentChargeSpecification",priceCurrency:i,price:t*1e3,unitCode:"MON",billingIncrement:1,billingPeriod:"P1M",priceType:"Subscription",maxPrice:t},eligibleQuantity:{"@type":"QuantitativeValue",value:1,unitCode:"MON"}}},c=await q({data:s,fileName:"fees",homeServerUrl:n,accessToken:o});return x.iid.v1beta1.LinkedResource.fromPartial({id:"{id}#fee",type:"pricingList",proof:c.proof,right:"",encrypted:"false",mediaType:"application/json",description:"Pricing List",serviceEndpoint:c.serviceEndpoint})}async updateOracleDomain(e,t){let i=this.wallet.wallet?.address;if(!this.wallet.signXClient||!this.wallet.wallet||!i)throw new Error("SignX client or wallet not found");let n={typeUrl:"/ixo.iid.v1beta1.MsgDeleteService",value:x.iid.v1beta1.MsgDeleteService.fromPartial({id:e,serviceId:`${e}#api`,signer:i})},o={typeUrl:"/ixo.iid.v1beta1.MsgDeleteService",value:x.iid.v1beta1.MsgDeleteService.fromPartial({id:e,serviceId:`${e}#ws`,signer:i})},s={typeUrl:"/ixo.iid.v1beta1.MsgAddService",value:x.iid.v1beta1.MsgAddService.fromPartial({id:e,serviceData:x.iid.v1beta1.Service.fromPartial({id:`${e}#api`,type:"oracleService",serviceEndpoint:t}),signer:i})},c={typeUrl:"/ixo.iid.v1beta1.MsgAddService",value:x.iid.v1beta1.MsgAddService.fromPartial({id:e,serviceData:x.iid.v1beta1.Service.fromPartial({id:`${e}#ws`,type:"wsService",serviceEndpoint:t}),signer:i})};h.info(`Sign to update oracle domain for entity ${e}`);let a=await this.wallet.signXClient.transact([n,o,s,c],this.wallet.wallet);this.wallet.signXClient.displayTransactionQRCode(JSON.stringify(a)),await this.wallet.signXClient.pollNextTransaction(),await this.wallet.signXClient.awaitTransaction(),h.success(`Oracle domain updated to ${t}`)}async addControllerToEntity(e,t){let i=this.wallet.wallet?.address;if(!this.wallet.signXClient||!this.wallet.wallet||!i)throw new Error("SignX client or wallet not found");let n={typeUrl:"/ixo.iid.v1beta1.MsgAddController",value:x.iid.v1beta1.MsgAddController.fromPartial({id:e,controllerDid:t,signer:i})};h.info(`Sign to add controller ${t} to entity ${e}`);let o=await this.wallet.signXClient.transact([n],this.wallet.wallet);this.wallet.signXClient.displayTransactionQRCode(JSON.stringify(o)),await this.wallet.signXClient.pollNextTransaction(),await this.wallet.signXClient.awaitTransaction(),h.success(`Controller ${t} added to entity ${e}`)}async createOracleConfigFiles({oracleName:e,entityDid:t,price:i,oracleAccountAddress:n,homeServerUrl:o,accessToken:s}){let c=this.wallet.wallet?.address;if(!this.wallet.signXClient||!this.wallet.wallet||!c)throw new Error("SignX client or wallet not found");let l=(await Promise.all([this.createAuthZConfig({oracleName:e,entityDid:t,oracleAccountAddress:n,homeServerUrl:o,accessToken:s}),this.createFeesConfig({entityDid:t,price:i,denom:this.config.getValue("network")==="devnet"?"uixo":"ibc/6BBE9BD4246F8E04948D5A4EEE7164B2630263B9EBB5E7DC5F0A46C62A2FF97B",homeServerUrl:o,accessToken:s})])).map(p=>({typeUrl:"/ixo.iid.v1beta1.MsgAddLinkedResource",value:x.iid.v1beta1.MsgAddLinkedResource.fromPartial({id:t,linkedResource:x.iid.v1beta1.LinkedResource.fromPartial({id:p.id,description:p.description,type:p.type,proof:p.proof,mediaType:p.mediaType,encrypted:p.encrypted,serviceEndpoint:p.serviceEndpoint}),signer:c})}));h.info("Sign to edit the entity and add the config files");let d=await this.wallet.signXClient.transact(l,this.wallet.wallet);return this.wallet.signXClient.displayTransactionQRCode(JSON.stringify(d)),await this.wallet.signXClient.pollNextTransaction(),await this.wallet.signXClient.awaitTransaction()}async createDomainCard({profile:e,entityDid:t,homeServerUrl:i,accessToken:n}){let o=new Date().toISOString(),s={"@context":["https://www.w3.org/ns/credentials/v2","https://w3id.org/ixo/context/v1",{schema:"https://schema.org/",ixo:"https://w3id.org/ixo/vocab/v1",prov:"http://www.w3.org/ns/prov#",proj:"https://linked.data.gov.au/def/project#",xsd:"http://www.w3.org/2001/XMLSchema#",id:"@id",type:"@type","ixo:vector":{"@container":"@list","@type":"xsd:double"},"@protected":!0}],id:`${t}#dmn`,type:["VerifiableCredential","ixo:DomainCard"],issuer:{id:this.wallet.did},validFrom:o,credentialSchema:{id:"https://github.com/ixoworld/domainCards/schemas/ixo-domain-card-1.json",type:"JsonSchema"},credentialSubject:{id:t,type:["ixo:oracle"],additionalType:["schema:Organization"],name:e.name,alternateName:e.orgName!==e.name?[e.orgName]:void 0,description:e.description,logo:{type:"schema:ImageObject",id:e.logo,contentUrl:e.logo},image:[{type:"schema:ImageObject",id:e.coverImage,contentUrl:e.coverImage}],address:{type:"schema:PostalAddress",addressLocality:e.location},...e.url?{url:e.url}:{}}},c=await q({data:s,fileName:"domainCard",homeServerUrl:i,accessToken:n});return x.iid.v1beta1.LinkedResource.fromPartial({id:"{id}#dmn",type:"domainCard",proof:c.proof,right:"",encrypted:"false",mediaType:"application/json",description:"Domain Card",serviceEndpoint:c.serviceEndpoint})}async addProfile({orgName:e,name:t,logo:i,coverImage:n,location:o,description:s,homeServerUrl:c,accessToken:a}){let d=await q({data:{"@context":{ixo:"https://w3id.org/ixo/ns/protocol/","@id":"@type",type:"@type","@protected":!1},id:"ixo:entity#profile",type:"profile",orgName:e,name:t,image:n,logo:i,brand:e,location:o,description:s},fileName:"profile",homeServerUrl:c,accessToken:a});return x.iid.v1beta1.LinkedResource.fromPartial({id:"{id}#pro",type:"Settings",description:"Profile",mediaType:"application/json",serviceEndpoint:d.serviceEndpoint,proof:d.proof,encrypted:"false",right:""})}addServices(e,t){e.value.service.push(...t.map(i=>x.iid.v1beta1.Service.fromPartial(i)))}setParentProtocol(e,t){e.value.context.push(...ft.iid.createAgentIidContext([{key:"class",val:t}]))}async submitToDomainIndexer(e){let t=this.config.getValue("network")??"devnet",i=B[t];try{let n=await fetch(i,{method:"POST",headers:{accept:"application/json","Content-Type":"application/json"},body:JSON.stringify({did:e})});if(!n.ok){let o=await n.text();h.warn(`Failed to submit to domain indexer: ${n.status} ${o}`);return}h.success("Domain card submitted to domain indexer")}catch(n){h.warn(`Error submitting to domain indexer: ${n instanceof Error?n.message:String(n)}`)}}async execute(e){if(!this.wallet.signXClient||!this.wallet.wallet)throw new Error("SignX client not found");let{matrixHomeServerUrl:t}=e;h.info("Creating Oracle Wallet and Matrix Account");let i=await mr({message:"Enter a 6-digit PIN to secure your Matrix Vault:",placeholder:"123456",validate(y){return J(y)}});lr(i)&&(h.error("User cancelled"),process.exit(1));let n=await ie({pin:i,oracleName:e.oracleConfig.oracleName,network:this.config.getValue("network"),oracleAvatarUrl:e.profile.logo,matrixHomeServerUrl:t},async y=>{await this.wallet.sendTokens(y,25e4)}),o=n.matrixHomeServerUrl,s=n.matrixAccessToken;h.info("Adding profile");let c=await this.addProfile({...e.profile,homeServerUrl:o,accessToken:s}),a=this.buildMsgCreateEntity(t);a.value.linkedResource.push(c),h.info("Adding services"),this.addServices(a,e.services),h.info("Adding parent protocol"),this.setParentProtocol(a,e.parentProtocol),this.addLinkedAccounts(a,{oracleAccountAddress:n.address}),h.info("Sign this transaction to create the entity");let l=await this.wallet.signXClient.transact([a],this.wallet.wallet);this.wallet.signXClient.displayTransactionQRCode(JSON.stringify(l)),await this.wallet.signXClient.pollNextTransaction();let d=await this.wallet.signXClient.awaitTransaction();h.success("Entity created -- wait to attach the required config files");let m=Oe.common.getValueFromEvents(d,"wasm","token_id");h.info("Creating domain card");let p=await this.createDomainCard({profile:e.profile,entityDid:m,homeServerUrl:o,accessToken:s});if(this.wallet.wallet?.address){let y={typeUrl:"/ixo.iid.v1beta1.MsgAddLinkedResource",value:x.iid.v1beta1.MsgAddLinkedResource.fromPartial({id:m,linkedResource:x.iid.v1beta1.LinkedResource.fromPartial({id:p.id,description:p.description,type:p.type,proof:p.proof,mediaType:p.mediaType,encrypted:p.encrypted,serviceEndpoint:p.serviceEndpoint}),signer:this.wallet.wallet.address})};h.info("Sign to add domain card to the entity");let P=await this.wallet.signXClient.transact([y],this.wallet.wallet);this.wallet.signXClient.displayTransactionQRCode(JSON.stringify(P)),await this.wallet.signXClient.pollNextTransaction(),await this.wallet.signXClient.awaitTransaction(),h.success("Domain card added to entity")}await this.createOracleConfigFiles({oracleName:e.oracleConfig.oracleName,price:e.oracleConfig.price,oracleAccountAddress:n.address,entityDid:m,homeServerUrl:o,accessToken:s}),h.success("Entity created -- config files attached"),await re({baseUrl:o,accessToken:s,userId:n.matrixUserId,deviceId:""});let v=dr();v.start("Creating Entity Matrix Room..."),v.stop("Room created -- room joined"),h.warn("Please save the following information in a secure location as it is not stored:"),h.info("ORACLE ACCOUNT DETAILS");for(let y in n)h.info(`${y}: ${n[y]}`);return this.config.addValue("registerUserResult",n),this.config.addValue("entityDid",m),this.config.addValue("oracleMatrixHomeServerUrl",t),h.info("Submitting domain card to domain indexer"),await this.submitToDomainIndexer(m),m}};var $=class{constructor(e,t){this.wallet=e;this.config=t}name="create-entity";description="Create an entity";async execute(){this.config.getValue("network")||await S(this.config);let t=this.wallet.matrixHomeServer??L[this.config.getValue("network")??"devnet"],i=await w.group({matrixHomeServerUrl:()=>w.text({message:"Matrix homeserver URL for the oracle:",initialValue:t,defaultValue:t,validate(a){return Q(a)}}),oracleName:()=>w.text({message:"What is the name of the oracle?",initialValue:"My oracle",validate(a){return T(a,"Oracle name is required")}}),oraclePrice:()=>w.text({message:"What is the price of the oracle in IXO CREDITS?",initialValue:"100",validate(a){return Xe(parseInt(a??""),"Oracle price is required and must be a number")}}),profile:()=>w.group({orgName:()=>w.text({message:"What is the name of the organization?",initialValue:"IXO",validate(a){return T(a,"Organization name is required")}}),name:()=>w.text({message:"What is the name of the profile?",initialValue:"My oracle",validate(a){return T(a,"Profile name is required")}}),logo:({results:a})=>w.text({message:"What is the logo of the profile?",initialValue:`https://api.dicebear.com/8.x/bottts/svg?seed=${a?.name??"IXO"}`,defaultValue:`https://api.dicebear.com/8.x/bottts/svg?seed=${a?.name??"IXO"}`,validate(l){return l?_(l,"Logo is required or a valid URL"):`https://api.dicebear.com/8.x/bottts/svg?seed=${a?.name??"IXO"}`}}),coverImage:({results:a})=>w.text({message:"What is the cover image of the profile?",initialValue:a.logo,defaultValue:a.logo,validate(l){return l?_(l,"Cover image is required or a valid URL"):a.logo}}),location:()=>w.text({message:"What is the location of your domain?",initialValue:"New York, NY",validate(a){return T(a,"Location is required")}}),description:()=>w.text({message:"What is the description of the entity (profile)?",initialValue:"We are a company that helps you with daily tasks",validate(a){return T(a,"Description is required")}}),url:()=>w.text({message:"What is the website URL of the oracle? (optional, press Enter to skip)",placeholder:"https://your-oracle-website.com"})}),parentProtocol:()=>w.select({message:"What is the parent protocol of the entity?",options:[{value:"did:ixo:entity:1a76366f16570483cea72b111b27fd78",label:"IXO Oracle Protocol",hint:"default protocol"}],initialValue:"did:ixo:entity:1a76366f16570483cea72b111b27fd78"}),apiUrl:()=>w.text({message:"What is the API URL of the oracle?",initialValue:"http://localhost:4000",validate(a){return _(a,"API URL is required or a valid URL")}})},{onCancel:()=>{w.cancel("Operation cancelled."),process.exit(0)}}),o=await new O(this.wallet,this.config).execute({oracleConfig:{oracleName:i.oracleName,price:parseInt(i.oraclePrice)},profile:{orgName:i.profile.orgName,name:i.profile.name,logo:i.profile.logo,coverImage:i.profile.coverImage,location:i.profile.location,description:i.profile.description,...i.profile.url?{url:i.profile.url}:{}},services:[{id:"{id}#api",serviceEndpoint:i.apiUrl,type:"oracleService"},{id:"{id}#ws",serviceEndpoint:i.apiUrl,type:"wsService"}],parentProtocol:i.parentProtocol,matrixHomeServerUrl:i.matrixHomeServerUrl});w.log.info(`API for the oracle is: ${i.apiUrl} | You can change this after you deploy the oracle`);let c=`${We[this.config.getValue("network")??"devnet"]}/oracle/${o}/overview`;return w.log.info(`Oracle created successfully: ${o}`),w.log.info(`Oracle URL: ${c}`),{success:!0,data:`Entity created successfully: ${o}`}}};import*as E from"@clack/prompts";var ne=class{constructor(e,t){this.wallet=e;this.config=t}name="create-user";description="Create a new user";async execute(){let e=this.config.getValue("network");e||await S(this.config);let t=this.wallet.matrixHomeServer??L[this.config.getValue("network")??"devnet"],i=await E.text({message:"Matrix homeserver URL:",initialValue:t,defaultValue:t,validate(c){return Q(c)}});E.isCancel(i)&&(E.log.error("User cancelled"),process.exit(1));let n=await E.text({message:"Enter a 6-digit PIN to secure your Matrix Vault:",placeholder:"123456",validate(c){return J(c)}});E.isCancel(n)&&(E.log.error("User cancelled"),process.exit(1));let o=await E.text({message:"Enter your oracle name",initialValue:"My oracle",validate(c){return T(c,"Oracle name is required")}});E.isCancel(o)&&(E.log.error("User cancelled"),process.exit(1));let s=await ie({pin:n,oracleName:o,network:this.config.getValue("network")??e,oracleAvatarUrl:`https://api.dicebear.com/8.x/bottts/svg?seed=${o}`,matrixHomeServerUrl:i},async c=>{await this.wallet.sendTokens(c,15e4)});return await re({baseUrl:s.matrixHomeServerUrl,accessToken:s.matrixAccessToken,userId:s.matrixUserId,deviceId:""}),{success:!0,data:s}}};var H=class{constructor(e){this.registry=e}name="help";description="Show help information and available commands";async execute(){return{success:!0,data:`
|
|
3
|
+
IXO Oracles CLI - Help
|
|
4
|
+
|
|
5
|
+
USAGE:
|
|
6
|
+
oracles-cli [command] [options]
|
|
7
|
+
|
|
8
|
+
COMMANDS:
|
|
9
|
+
${this.registry.getAll().map(i=>` ${i.name.padEnd(15)} ${i.description}`).join(`
|
|
10
|
+
`)}
|
|
11
|
+
|
|
12
|
+
EXAMPLES:
|
|
13
|
+
oracles-cli --init Initialize a new IXO Oracle project
|
|
14
|
+
oracles-cli Launch interactive menu
|
|
15
|
+
oracles-cli help Show this help message
|
|
16
|
+
|
|
17
|
+
OPTIONS:
|
|
18
|
+
--init Initialize a new project (shortcut)
|
|
19
|
+
--help, -h Show help information
|
|
20
|
+
|
|
21
|
+
For more information, visit: https://github.com/ixoworld/ixo-oracles-cli
|
|
22
|
+
`}}};import*as g from"@clack/prompts";import{existsSync as ae}from"fs";import W from"path";import wt from"simple-git";import se from"fs";import oe from"path";function pr(r,e){return`
|
|
23
|
+
PORT=4000
|
|
24
|
+
ORACLE_NAME=${e.oracleName}
|
|
25
|
+
|
|
26
|
+
# Network
|
|
27
|
+
NETWORK=${r}
|
|
28
|
+
RPC_URL=${N[r]}
|
|
29
|
+
BLOCKSYNC_GRAPHQL_URL=${j[r]}
|
|
30
|
+
BLOCKSYNC_URI=${j[r]}
|
|
31
|
+
|
|
32
|
+
# Matrix
|
|
33
|
+
MATRIX_BASE_URL=${e.matrixBaseUrl}
|
|
34
|
+
MATRIX_ORACLE_ADMIN_ACCESS_TOKEN=${e.matrixAccessToken}
|
|
35
|
+
MATRIX_ORACLE_ADMIN_PASSWORD=${e.matrixPassword}
|
|
36
|
+
MATRIX_ORACLE_ADMIN_USER_ID=${e.matrixUserId}
|
|
37
|
+
MATRIX_RECOVERY_PHRASE="${e.matrixRecoveryPhrase}"
|
|
38
|
+
MATRIX_VALUE_PIN=${e.matrixPin}
|
|
39
|
+
MATRIX_ACCOUNT_ROOM_ID="${e.matrixRoomId}"
|
|
40
|
+
|
|
41
|
+
# Blockchain
|
|
42
|
+
SECP_MNEMONIC="${e.mnemonic}"
|
|
43
|
+
ORACLE_ENTITY_DID=${e.entityDid}
|
|
44
|
+
|
|
45
|
+
# Database
|
|
46
|
+
SQLITE_DATABASE_PATH=./sqlite-db
|
|
47
|
+
REDIS_URL=redis://localhost:6379
|
|
48
|
+
|
|
49
|
+
# LLM (add your API keys)
|
|
50
|
+
OPENAI_API_KEY=
|
|
51
|
+
OPEN_ROUTER_API_KEY=
|
|
52
|
+
|
|
53
|
+
# External Services (configure these for your deployment)
|
|
54
|
+
MEMORY_MCP_URL=${Ce[r]}
|
|
55
|
+
MEMORY_ENGINE_URL=${ve[r]}
|
|
56
|
+
|
|
57
|
+
# FIRECRWAL -> check the docs https://docs.firecrawl.dev/mcp-server
|
|
58
|
+
FIRECRAWL_MCP_URL=
|
|
59
|
+
DOMAIN_INDEXER_URL=${B[r]}
|
|
60
|
+
SANDBOX_MCP_URL=${Re[r]}
|
|
61
|
+
|
|
62
|
+
# Observability (optional)
|
|
63
|
+
LANGSMITH_TRACING=true
|
|
64
|
+
LANGSMITH_ENDPOINT=
|
|
65
|
+
LANGSMITH_API_KEY=
|
|
66
|
+
LANGSMITH_PROJECT="${e.oracleName}_${r}"
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
DISABLE_CREDITS=true
|
|
70
|
+
CORS_ORIGIN=*
|
|
71
|
+
SUBSCRIPTION_URL=${Ee[r]}
|
|
72
|
+
|
|
73
|
+
### BACKUP \u2014 save these securely (values above are already set)
|
|
74
|
+
# ORACLE_ADDRESS=${e.oracleAddress}
|
|
75
|
+
# ORACLE_DID=${e.oracleDid}
|
|
76
|
+
`}function gr(r,e){return`# To fill in the blank values, run: oracles-cli create-entity (select ${r})
|
|
77
|
+
|
|
78
|
+
PORT=4000
|
|
79
|
+
ORACLE_NAME=${e}
|
|
80
|
+
|
|
81
|
+
# Network
|
|
82
|
+
NETWORK=${r}
|
|
83
|
+
RPC_URL=${N[r]}
|
|
84
|
+
BLOCKSYNC_GRAPHQL_URL=${j[r]}
|
|
85
|
+
BLOCKSYNC_URI=${j[r]}
|
|
86
|
+
|
|
87
|
+
# Matrix
|
|
88
|
+
MATRIX_BASE_URL=${L[r]}
|
|
89
|
+
MATRIX_ORACLE_ADMIN_ACCESS_TOKEN=
|
|
90
|
+
MATRIX_ORACLE_ADMIN_PASSWORD=
|
|
91
|
+
MATRIX_ORACLE_ADMIN_USER_ID=
|
|
92
|
+
MATRIX_RECOVERY_PHRASE=
|
|
93
|
+
MATRIX_VALUE_PIN=
|
|
94
|
+
MATRIX_ACCOUNT_ROOM_ID=
|
|
95
|
+
|
|
96
|
+
# Blockchain
|
|
97
|
+
SECP_MNEMONIC=
|
|
98
|
+
ORACLE_ENTITY_DID=
|
|
99
|
+
|
|
100
|
+
# Database
|
|
101
|
+
SQLITE_DATABASE_PATH=./sqlite-db
|
|
102
|
+
REDIS_URL=redis://localhost:6379
|
|
103
|
+
|
|
104
|
+
# LLM (add your API keys)
|
|
105
|
+
OPENAI_API_KEY=
|
|
106
|
+
OPEN_ROUTER_API_KEY=
|
|
107
|
+
|
|
108
|
+
# External Services (configure these for your deployment)
|
|
109
|
+
MEMORY_MCP_URL=${Ce[r]}
|
|
110
|
+
MEMORY_ENGINE_URL=${ve[r]}
|
|
111
|
+
|
|
112
|
+
# FIRECRWAL -> check the docs https://docs.firecrawl.dev/mcp-server
|
|
113
|
+
FIRECRAWL_MCP_URL=
|
|
114
|
+
DOMAIN_INDEXER_URL=${B[r]}
|
|
115
|
+
SANDBOX_MCP_URL=${Re[r]}
|
|
116
|
+
|
|
117
|
+
# Observability (optional)
|
|
118
|
+
LANGSMITH_TRACING=true
|
|
119
|
+
LANGSMITH_ENDPOINT=
|
|
120
|
+
LANGSMITH_API_KEY=
|
|
121
|
+
LANGSMITH_PROJECT="${e}_${r}"
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
# Features (optional)
|
|
125
|
+
# DISABLE_CREDITS=false
|
|
126
|
+
# CORS_ORIGIN=*
|
|
127
|
+
# SUBSCRIPTION_URL=${Ee[r]}
|
|
128
|
+
`}function Ue(r,e){try{se.writeFileSync(r,e),console.log("\u2705 env file created successfully at:",r)}catch(t){throw console.error("\u274C Failed to create env file:",r,t),t}}var ht=async r=>{let e=r.getOrThrow("oracleMatrixHomeServerUrl"),t=r.getOrThrow("network"),i=r.getOrThrow("registerUserResult"),n=await Pe({homeServerUrl:e,username:i.matrixUserId,password:i.matrixPassword,deviceName:i.matrixDeviceName}),o=r.getOrThrow("projectPath"),s=oe.join(o,"apps","app");console.log("Creating env files in:",s),se.existsSync(s)||(console.log("Creating directory:",s),se.mkdirSync(s,{recursive:!0}));let c=r.getValue("projectName")??"",a=pr(t,{oracleName:c,network:t,matrixBaseUrl:e,matrixAccessToken:n.accessToken,matrixPassword:i.matrixPassword,matrixUserId:i.matrixUserId,matrixRecoveryPhrase:i.matrixRecoveryPhrase,matrixPin:i.pin,matrixRoomId:i.matrixRoomId,mnemonic:i.mnemonic,entityDid:r.getOrThrow("entityDid"),oracleAddress:i.address,oracleDid:i.did}),l=`.env.${t}`;Ue(oe.join(s,l),a),Ue(oe.join(s,".env"),a);let d=[{net:"devnet",filename:".env.devnet"},{net:"testnet",filename:".env.testnet"},{net:"mainnet",filename:".env.mainnet"}];for(let{net:m,filename:p}of d){if(m===t)continue;let v=oe.join(s,p);if(se.existsSync(v))continue;let y=gr(m,c);Ue(v,y)}};var ce=class{constructor(e,t){this.config=e;this.wallet=t}name="init";description="Initialize Project";async getProjectInput(){let e=await g.text({message:"What is your project named?",placeholder:"my-ixo-project",validate(o){if(!o)return"Project name is required"}});g.isCancel(e)&&(g.cancel("Operation cancelled."),process.exit(0));let t=String(e),i,n;return t.includes("/")||t.includes("\\")?(i=t,n=W.basename(t)):(n=t,i=W.join(process.cwd(),n)),this.isValidProjectName(n)||(g.note("Invalid project name. Using a valid name instead.","Warning"),n=this.sanitizeProjectName(n),i=W.join(W.dirname(i),n)),{projectPath:i,projectName:n}}isValidProjectName(e){return/^[a-zA-Z][a-zA-Z0-9-_]*$/.test(e)&&e.length>0&&e.length<=50}sanitizeProjectName(e){return e.replace(/[^a-zA-Z0-9-_]/g,"-").replace(/^-+|-+$/g,"").toLowerCase().substring(0,50)}async confirmProjectCreation(e,t){if(ae(e)){let o=await g.confirm({message:`Directory "${e}" already exists. Do you want to overwrite it?`,initialValue:!1});return g.isCancel(o)&&(g.cancel("Operation cancelled."),process.exit(0)),o}let n=await g.confirm({message:`Create IXO project "${t}" in "${e}"?`,initialValue:!0});return g.isCancel(n)&&(g.cancel("Operation cancelled."),process.exit(0)),n}async selectRepo(){let e=await g.select({message:"Select a template to clone",options:[{value:"git@github.com:ixoworld/qiforge.git",label:"IXO Oracles (Default)"},{label:"Custom template",value:"custom"}]});if(g.isCancel(e)&&(g.cancel("Operation cancelled."),process.exit(0)),e==="custom"){let t=await g.text({message:"Enter the custom template URL"});return g.isCancel(t)&&(g.cancel("Operation cancelled."),process.exit(0)),t}return e}async cloneRepo(e,t,i=!1){let n=wt(),o=g.spinner();try{if(o.start("Cloning repository..."),i&&ae(t)){let{rmSync:l}=await import("fs");l(t,{recursive:!0,force:!0})}await n.clone(e,t);let s=W.join(t,".git");if(ae(s)){let{rmSync:l}=await import("fs");l(s,{recursive:!0,force:!0})}await wt(t).init(),o.stop("Repository cloned successfully"),g.log.info("Creating Oracle Entity and Matrix Account"),(await new $(this.wallet,this.config).execute()).success?g.log.info("Oracle Entity and Matrix Account created successfully"):g.log.error("Failed to create Oracle Entity and Matrix Account"),await ht(this.config),g.log.success(`
|
|
129
|
+
\u2705 IXO project created successfully!
|
|
130
|
+
|
|
131
|
+
\u{1F4C1} Location: ${t}
|
|
132
|
+
\u{1F680} Next steps:
|
|
133
|
+
cd ${W.basename(t)}
|
|
134
|
+
pnpm install
|
|
135
|
+
pnpm build
|
|
136
|
+
cd apps/app
|
|
137
|
+
pnpm start:dev`)}catch(s){throw o.stop("Failed to clone repository"),s}}async execute(){try{let{projectPath:e,projectName:t}=await this.getProjectInput();if(!await this.confirmProjectCreation(e,t))return{success:!1,data:"Project creation cancelled"};this.config.addValue("projectPath",e),this.config.addValue("projectName",t);let n=await this.selectRepo();this.config.addValue("repo",n);let o=ae(e);return await this.cloneRepo(n,e,o),{success:!0,data:`Project "${t}" created successfully in "${e}"`}}catch(e){return{success:!1,error:e instanceof Error?e.message:"Unknown error occurred"}}}};import{confirm as ur}from"@clack/prompts";var le=class{constructor(e){this.wallet=e}name="logout";description="Logout command";async execute(){return await ur({message:"Are you sure you want to logout?",initialValue:!1})?(await this.wallet.clearWallet(),{success:!0,data:"Logged out successfully"}):{success:!1,error:"Logout cancelled"}}};import{toHex as fr}from"@cosmjs/encoding";import{createRegistry as hr}from"@ixo/impactxclient-sdk";import{SignX as yt,SIGN_X_LOGIN_ERROR as wr,SIGN_X_LOGIN_SUCCESS as yr,SIGN_X_TRANSACT_ERROR as xr,SIGN_X_TRANSACT_SUCCESS as vr}from"@ixo/signx-sdk";import Cr from"qrcode-terminal";var xt={devnet:"https://signx.devnet.ixo.earth",testnet:"https://signx.testnet.ixo.earth",mainnet:"https://signx.ixo.earth"},X=class{signXClient;_loginData;get loginData(){return this._loginData}static loadFromWallet(e){return new yt({endpoint:xt[e.network],sitename:"IXO Oracles CLI",network:e.network})}constructor(e){this.signXClient=new yt({endpoint:xt[e],sitename:"IXO Oracles CLI",network:e})}async login(){let e=await this.signXClient.login({pollingInterval:2e3,matrix:!0});return this._loginData=e,e}displayStyledQRCode(e,t){let i=typeof e=="string"?e:JSON.stringify(e);console.log(`
|
|
138
|
+
`+" ".repeat(5)+"\u{1F510} "+t),console.log(" ".repeat(5)+"\u{1F4F1} Scan with IXO app"),console.log(" ".repeat(5)+"\u2501".repeat(30)),Cr.generate(i,{small:!0}),console.log(" ".repeat(5)+`\u23F3 Waiting...
|
|
139
|
+
`)}displayQRCode(e){this.displayStyledQRCode(e,"Login with SignX")}async awaitLogin(){return new Promise((e,t)=>{try{this.signXClient.on(yr,i=>{if(!i.data){t(new Error("Login failed"));return}if(!i.data.matrix){t(new Error("Matrix login failed"));return}e(i.data)}),this.signXClient.on(wr,i=>{console.log("Login error:",i),t(i)})}catch(i){console.error("Error in connecting:",i),t(i)}})}async transact(e,t,i){let n=hr();return this.signXClient.transact({address:t.address,did:t.did,pubkey:t.pubKey,timestamp:new Date().toISOString(),transactions:[{sequence:1,txBodyHex:fr(n.encodeTxBody({messages:e,memo:i||""}))}]})}async awaitTransaction(){return new Promise((e,t)=>{try{this.signXClient.on(vr,i=>{e(i.data)}),this.signXClient.on(xr,i=>{t(i)})}catch(i){console.error("Error in connecting:",i),t(i)}})}async pollNextTransaction(){return this.signXClient.pollNextTransaction()}displayTransactionQRCode(e){this.displayStyledQRCode(e,"SIGNX TRANSACTION")}};var de=class{constructor(e,t){this.wallet=e;this.config=t}name="signx-login";description="Login with SignX wallet";async execute(){try{let e=await S(this.config),t=new X(e),i=await t.login();t.displayQRCode(i);let n=await t.awaitLogin();return this.wallet.setWallet(n),this.wallet.setSignXClient(t),{success:!0,data:{message:"Successfully logged in with SignX!",wallet:{address:n.address,did:n.did,name:n.name}}}}catch(e){return{success:!1,error:e instanceof Error?`SignX login failed: ${e.message}`:"Unknown error"}}}};import*as I from"@clack/prompts";var me=class{constructor(e,t){this.wallet=e;this.config=t}name="update-oracle-api-url";description="Update the oracle API domain (default is localhost)";async execute(){this.config.getValue("network")||await S(this.config);let t=await I.group({entityDid:()=>I.text({message:"What is the DID of the entity you want to update?",initialValue:this.config.getValue("entityDid")?.toString()??"",validate(i){return F(i)}}),apiUrl:()=>I.text({message:"What is the new API URL (domain) for the oracle?",initialValue:"http://localhost:4000",validate(i){return _(i,"API URL is required and must be a valid URL")}})},{onCancel:()=>{I.cancel("Operation cancelled."),process.exit(0)}});try{let i=new O(this.wallet,this.config);return I.log.info(`Updating oracle domain for entity ${t.entityDid} to ${t.apiUrl}`),await i.updateOracleDomain(t.entityDid,t.apiUrl),{success:!0,data:`Oracle domain updated to ${t.apiUrl} for entity ${t.entityDid}`}}catch(i){return{success:!1,error:i instanceof Error?i.message:String(i)}}}};import*as C from"@clack/prompts";var pe=class{constructor(e,t){this.wallet=e;this.config=t;this.createEntity=new O(this.wallet,this.config)}name="update-entity";description="Update an entity (add controllers, etc.)";createEntity;async execute(){this.config.getValue("network")||await S(this.config);let t=await C.group({entityDid:()=>C.text({message:"What is the DID of the entity you want to update?",initialValue:this.config.getValue("entityDid")?.toString()??"",validate(i){return F(i)}}),action:()=>C.select({message:"What would you like to do?",options:[{value:"add-controller",label:"Add Controller",hint:"Add a new controller DID to the entity"}],initialValue:"add-controller"}),controllerDid:async({results:i})=>{if(i.action!=="add-controller")throw new Error("Unknown action");let n=await C.text({message:"What is the DID of the controller you want to add?",validate(o){return F(o)}});return C.isCancel(n)&&(C.cancel("Operation cancelled."),process.exit(0)),n}},{onCancel:()=>{C.cancel("Operation cancelled."),process.exit(0)}});try{if(t.action==="add-controller"&&typeof t.controllerDid=="string"){let i=t.controllerDid,n=t.entityDid;return C.log.info(`Adding controller ${i} to entity ${n}`),await this.createEntity.addControllerToEntity(n,i),C.log.success(`Controller ${i} successfully added to entity ${n}`),{success:!0,data:`Controller ${i} added to entity ${n}`}}return{success:!1,error:"Unknown action"}}catch(i){return{success:!1,error:i instanceof Error?i.message:String(i)}}}};var ke=class extends Error{constructor(t,i="CLI_ERROR",n){super(t);this.code=i;this.suggestions=n;this.name="CLIError"}};function ge(r){r instanceof ke&&(console.error(`
|
|
140
|
+
\u274C ${r.name}: ${r.message}`),r.suggestions?.length&&(console.error(`
|
|
141
|
+
Suggestions:`),r.suggestions.forEach(e=>console.error(` \u2022 ${e}`))),process.exit(1)),r instanceof Error&&(console.error(`
|
|
142
|
+
\u274C Unexpected Error: ${r.message}`),r.stack&&(console.error(`
|
|
143
|
+
Stack trace:`),console.error(r.stack)),process.exit(1)),console.error(`
|
|
144
|
+
\u274C Unknown error occurred`,r),process.exit(1)}var ue=class r{config={};static instance;constructor(){}static getInstance(){return r.instance||(r.instance=new r),r.instance}addValue(e,t){this.config[e]=t}getValue(e){return this.config[e]}getOrThrow(e){let t=this.getValue(e);if(!t)throw new Error(`Value ${e} is not set`);return t}getConfig(){return this.config}deleteValue(e){delete this.config[e]}};import{log as b}from"@clack/prompts";import{cosmos as vt}from"@ixo/impactxclient-sdk";import{existsSync as Me,readFileSync as Rr,writeFileSync as Er}from"fs";import{unlink as Sr}from"fs/promises";import Ar from"os";import Ir from"path";var k=Ir.join(Ar.homedir(),".wallet.json"),fe=class{wallet;signXClient;config;constructor(e){this.config=e,this.loadWallet()}setSignXClient(e){this.signXClient=e}loadWallet(){if(Me(k))try{let e=Rr(k,"utf8");if(this.wallet=JSON.parse(e),!this.wallet.matrix?.userId||!this.wallet.matrix.userId.includes(":")){b.warning("Wallet is missing valid Matrix credentials. Please re-authenticate via SignX."),this.wallet=void 0;return}let t=this.wallet.network;if(!t){let i=this.wallet.matrix.userId.split(":")[1];if(t={"devmx.ixo.earth":"devnet","testmx.ixo.earth":"testnet","mx.ixo.earth":"mainnet"}[i],!t)throw new Error(`Cannot determine network from matrix domain: ${i}`);this.wallet.network=t}this.config.addValue("network",t),this.setSignXClient(new X(t)),b.success(`Welcome back, ${this.wallet.name}!`),b.info(`Network: ${t}`)}catch(e){b.warning(`Failed to load wallet file: ${e instanceof Error?e.message:String(e)}`),this.wallet=void 0}else b.warning("No wallet file found")}setWallet(e){try{this.wallet=e;let t=JSON.stringify(e,null,2);Er(k,t,"utf8"),b.success(`Wallet saved successfully to: ${k}`)}catch(t){throw b.error(`Failed to save wallet: ${t instanceof Error?t.message:String(t)}`),new Error("Failed to save wallet file")}}checkWalletExists(){return Me(k)&&this.wallet!==void 0}async clearWallet(){this.wallet=void 0;try{Me(k)&&(await Sr(k),b.success("Wallet file deleted successfully"))}catch(e){b.error(`Failed to delete wallet file: ${e instanceof Error?e.message:String(e)}`)}}get did(){return this.wallet?.did}get address(){return this.wallet?.address}get name(){return this.wallet?.name}get pubKey(){return this.wallet?.pubKey}get algo(){return this.wallet?.algo}get matrix(){return this.wallet?.matrix}get matrixHomeServer(){let e=this.wallet?.matrix?.userId;return!e||!e.includes(":")?void 0:`https://${e.split(":")[1]}`}reloadWallet(){this.loadWallet()}async sendTokens(e,t){if(!this.address||!this.signXClient||!this.wallet)throw new Error("Wallet not loaded");let i={typeUrl:"/cosmos.bank.v1beta1.MsgSend",value:vt.bank.v1beta1.MsgSend.fromPartial({fromAddress:this.address,toAddress:e,amount:[vt.base.v1beta1.Coin.fromPartial({amount:t.toString(),denom:"uixo"})]})},n=await this.signXClient?.transact([i],this.wallet);return this.signXClient?.displayTransactionQRCode(JSON.stringify(n)),await this.signXClient?.pollNextTransaction(),await this.signXClient?.awaitTransaction()}};var Le=class{registry;config;wallet;constructor(){this.registry=new z,this.config=ue.getInstance(),this.wallet=new fe(this.config)}registerCommands(){this.registry.register(new ce(this.config,this.wallet)),this.registry.register(new $(this.wallet,this.config)),this.registry.register(new pe(this.wallet,this.config)),this.registry.register(new me(this.wallet,this.config)),this.registry.register(new ne(this.wallet,this.config)),this.registry.register(new le(this.wallet)),this.registry.register(new H(this.registry))}async showHelp(){this.wallet.setWallet({address:"0x0000000000000000000000000000000000000000",algo:"secp",did:"did:ixo:entity:1a76366f16570483cea72b111b27fd78",network:"devnet",name:"My oracle",pubKey:"0x0400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",ledgered:!1,matrix:{accessToken:"",userId:"0x0000000000000000000000000000000000000000",address:"",roomId:""}}),this.registerCommands();let t=await new H(this.registry).execute();t.success&&t.data&&console.log(t.data)}async handleAuthentication(){if(!this.wallet.checkWalletExists()){let e=await Rt({message:"Login with SignX",options:[{value:"login",label:"Login"},{value:"exit",label:"Exit"}]});switch(Ct(e)&&(De("Operation cancelled."),M.exit(0)),String(e)){case"login":{(await new de(this.wallet,this.config).execute()).success&&G.success("Login successful");return}case"exit":{De("Operation cancelled."),M.exit(0);return}default:throw new Error(`Unknown command: ${e}`)}}}async executeCommand(e){let t=this.registry.get(e);if(!t)throw new Error(`Unknown command: ${e}`);let i=Nr();i.start(`Executing ${t.name}...`);let n=await t.execute();i.stop(`${t.name} completed`),n.success?(G.success(`${t.name} completed successfully!`),n.data&&G.info(JSON.stringify(n.data,null,2))):G.error(`${t.name} failed: ${n.error}`)}async interactiveMode(){br("IXO CLI"),G.warn("Keep your IXO Mobile App open while running the CLI; So u do not interrupt the signX session"),await this.handleAuthentication(),this.registerCommands();let e=await Rt({message:`Welcome ${this.wallet.name}, what would you like to do?`,options:[...this.registry.getCommandOptions()],initialValue:"init"});Ct(e)&&(De("Operation cancelled."),M.exit(0)),await this.executeCommand(String(e))}async argumentMode(e){let t=e[0];if(!t){await this.interactiveMode();return}if(t==="--init"){await this.handleAuthentication(),this.registerCommands(),await this.executeCommand("init");return}if(t==="--help"||t==="-h"){await this.showHelp();return}await this.handleAuthentication(),this.registerCommands(),await this.executeCommand(t)}async run(e){try{let t=e.slice(2);t.length===0?await this.interactiveMode():await this.argumentMode(t)}catch(t){ge(t)}Pr("Thanks for using IXO CLI!"),M.exit(0)}};M.on("uncaughtException",ge);M.on("unhandledRejection",ge);var Tr=new Le;Tr.run(M.argv);
|
|
145
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/cli.ts","../src/commands/index.ts","../src/commands/create-entity-command.ts","../src/utils/common.ts","../src/utils/entity.ts","../src/utils/account/matrix.ts","../src/utils/account/secretStorageKeys.ts","../src/utils/account/utils.ts","../src/utils/account/feegrant.ts","../src/utils/account/simplifiedRegistration.ts","../src/utils/matrix/upload-to-matrix.ts","../src/utils/createCIDFromBase64.ts","../src/commands/create-user-command.ts","../src/commands/help.command.ts","../src/commands/init.command.ts","../src/utils/create-project-env-file.ts","../src/commands/logout.commands.ts","../src/utils/signx/signx.ts","../src/commands/signX.commands.ts","../src/commands/update-domain-command.ts","../src/commands/update-entity-command.ts","../src/utils/errors.ts","../src/utils/runtime-config.ts","../src/utils/wallet.ts"],"sourcesContent":["import { cancel, intro, isCancel, log, outro, select, spinner } from '@clack/prompts';\nimport process from 'node:process';\nimport { CommandRegistry } from './commands';\nimport { CreateEntityCommand } from './commands/create-entity-command';\nimport { CreateUserCommand } from './commands/create-user-command';\nimport { HelpCommand } from './commands/help.command';\nimport { InitCommand } from './commands/init.command';\nimport { LogoutCommand } from './commands/logout.commands';\nimport { SignXLoginCommand } from './commands/signX.commands';\nimport { UpdateDomainCommand } from './commands/update-domain-command';\nimport { UpdateEntityCommand } from './commands/update-entity-command';\nimport { handleError } from './utils/errors';\nimport { RuntimeConfig } from './utils/runtime-config';\nimport { Wallet } from './utils/wallet';\n\nclass CLIManager {\n private registry: CommandRegistry;\n private config: RuntimeConfig;\n private wallet: Wallet;\n\n constructor() {\n this.registry = new CommandRegistry();\n this.config = RuntimeConfig.getInstance();\n this.wallet = new Wallet(this.config);\n }\n\n private registerCommands(): void {\n this.registry.register(new InitCommand(this.config, this.wallet));\n this.registry.register(new CreateEntityCommand(this.wallet, this.config));\n this.registry.register(new UpdateEntityCommand(this.wallet, this.config));\n this.registry.register(new UpdateDomainCommand(this.wallet, this.config));\n this.registry.register(new CreateUserCommand(this.wallet, this.config));\n this.registry.register(new LogoutCommand(this.wallet));\n this.registry.register(new HelpCommand(this.registry));\n }\n\n private async showHelp(): Promise<void> {\n // add fake wallet to the config\n this.wallet.setWallet({\n address: '0x0000000000000000000000000000000000000000',\n algo: 'secp',\n did: 'did:ixo:entity:1a76366f16570483cea72b111b27fd78',\n network: 'devnet',\n name: 'My oracle',\n pubKey:\n '0x0400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000',\n ledgered: false,\n matrix: {\n accessToken: '',\n userId: '0x0000000000000000000000000000000000000000',\n address: '',\n roomId: '',\n },\n });\n this.registerCommands();\n const helpCommand = new HelpCommand(this.registry);\n const result = await helpCommand.execute();\n if (result.success && result.data) {\n console.log(result.data);\n }\n }\n\n private async handleAuthentication(): Promise<void> {\n if (!this.wallet.checkWalletExists()) {\n const login = await select({\n message: 'Login with SignX',\n options: [\n { value: 'login', label: 'Login' },\n { value: 'exit', label: 'Exit' },\n ],\n });\n\n if (isCancel(login)) {\n cancel('Operation cancelled.');\n process.exit(0);\n }\n\n switch (String(login)) {\n case 'login': {\n const loginCommand = new SignXLoginCommand(this.wallet, this.config);\n const result = await loginCommand.execute();\n if (result.success) {\n log.success('Login successful');\n }\n return;\n }\n case 'exit': {\n cancel('Operation cancelled.');\n process.exit(0);\n return;\n }\n default: {\n throw new Error(`Unknown command: ${login}`);\n }\n }\n }\n }\n\n private async executeCommand(commandName: string): Promise<void> {\n const command = this.registry.get(commandName);\n if (!command) {\n throw new Error(`Unknown command: ${commandName}`);\n }\n\n const s = spinner();\n s.start(`Executing ${command.name}...`);\n\n const result = await command.execute();\n s.stop(`${command.name} completed`);\n\n if (result.success) {\n log.success(`${command.name} completed successfully!`);\n if (result.data) {\n log.info(JSON.stringify(result.data, null, 2));\n }\n } else {\n log.error(`${command.name} failed: ${result.error}`);\n }\n }\n\n private async interactiveMode(): Promise<void> {\n intro('IXO CLI');\n log.warn('Keep your IXO Mobile App open while running the CLI; So u do not interrupt the signX session');\n\n await this.handleAuthentication();\n this.registerCommands();\n\n const action = await select({\n message: `Welcome ${this.wallet.name}, what would you like to do?`,\n options: [...this.registry.getCommandOptions()],\n initialValue: 'init',\n });\n\n if (isCancel(action)) {\n cancel('Operation cancelled.');\n process.exit(0);\n }\n\n await this.executeCommand(String(action));\n }\n\n private async argumentMode(args: string[]): Promise<void> {\n const command = args[0];\n\n if (!command) {\n await this.interactiveMode();\n return;\n }\n\n // Handle special flags\n if (command === '--init') {\n await this.handleAuthentication();\n this.registerCommands();\n await this.executeCommand('init');\n return;\n }\n\n // Handle help\n if (command === '--help' || command === '-h') {\n await this.showHelp();\n return;\n }\n\n // Handle direct command execution\n await this.handleAuthentication();\n this.registerCommands();\n await this.executeCommand(command);\n }\n\n async run(args: string[]): Promise<void> {\n try {\n // Remove the first two args (node path and script path)\n const userArgs = args.slice(2);\n\n if (userArgs.length === 0) {\n await this.interactiveMode();\n } else {\n await this.argumentMode(userArgs);\n }\n } catch (error) {\n handleError(error);\n }\n\n outro('Thanks for using IXO CLI!');\n process.exit(0);\n }\n}\n\n// Handle uncaught errors\nprocess.on('uncaughtException', handleError);\nprocess.on('unhandledRejection', handleError);\n\n// Start the CLI\nconst cli = new CLIManager();\nvoid cli.run(process.argv);\n","import { CLIResult } from '../types';\n\nexport interface Command {\n name: string;\n description: string;\n execute: (...args: any[]) => Promise<CLIResult>;\n}\n\nexport class CommandRegistry {\n private commands: Map<string, Command>;\n\n constructor() {\n this.commands = new Map();\n }\n\n register(command: Command): void {\n this.commands.set(command.name, command);\n }\n\n get(name: string): Command | undefined {\n return this.commands.get(name);\n }\n\n getAll(): Command[] {\n return Array.from(this.commands.values());\n }\n\n getCommandOptions() {\n return this.getAll().map((cmd) => ({\n value: cmd.name,\n label: cmd.name,\n hint: cmd.description,\n }));\n }\n}\n","import * as p from '@clack/prompts';\nimport { NETWORK } from '@ixo/signx-sdk/types/types/transact';\nimport { Command } from '.';\nimport { CLIResult } from '../types';\nimport {\n checkRequiredMatrixUrl,\n checkRequiredNumber,\n checkRequiredString,\n checkRequiredURL,\n MatrixHomeServerUrl,\n PORTAL_URL,\n selectNetwork,\n} from '../utils/common';\nimport { CreateEntity } from '../utils/entity';\nimport { RuntimeConfig } from '../utils/runtime-config';\nimport { Wallet } from '../utils/wallet';\n\nexport class CreateEntityCommand implements Command {\n name = 'create-entity';\n description = 'Create an entity';\n\n constructor(private wallet: Wallet, private config: RuntimeConfig) {}\n\n async execute(): Promise<CLIResult> {\n const network = this.config.getValue('network') as NETWORK;\n if (!network) {\n await selectNetwork(this.config);\n }\n\n // Determine default Matrix homeserver URL from wallet or static map\n const defaultMatrixUrl =\n this.wallet.matrixHomeServer ?? MatrixHomeServerUrl[(this.config.getValue('network') as NETWORK) ?? 'devnet'];\n\n const results = await p.group(\n {\n matrixHomeServerUrl: () =>\n p.text({\n message: 'Matrix homeserver URL for the oracle:',\n initialValue: defaultMatrixUrl,\n defaultValue: defaultMatrixUrl,\n validate(value) {\n return checkRequiredMatrixUrl(value);\n },\n }),\n oracleName: () =>\n p.text({\n message: 'What is the name of the oracle?',\n initialValue: 'My oracle',\n validate(value) {\n return checkRequiredString(value, 'Oracle name is required');\n },\n }),\n oraclePrice: () =>\n p.text({\n message: 'What is the price of the oracle in IXO CREDITS?',\n initialValue: '100',\n validate(value) {\n return checkRequiredNumber(parseInt(value ?? ''), 'Oracle price is required and must be a number');\n },\n }),\n profile: () =>\n p.group({\n orgName: () =>\n p.text({\n message: 'What is the name of the organization?',\n initialValue: 'IXO',\n validate(value) {\n return checkRequiredString(value, 'Organization name is required');\n },\n }),\n name: () =>\n p.text({\n message: 'What is the name of the profile?',\n initialValue: 'My oracle',\n validate(value) {\n return checkRequiredString(value, 'Profile name is required');\n },\n }),\n logo: ({ results }) =>\n p.text({\n message: 'What is the logo of the profile?',\n initialValue: `https://api.dicebear.com/8.x/bottts/svg?seed=${results?.name ?? 'IXO'}`,\n defaultValue: `https://api.dicebear.com/8.x/bottts/svg?seed=${results?.name ?? 'IXO'}`,\n validate(value) {\n if (!value) return `https://api.dicebear.com/8.x/bottts/svg?seed=${results?.name ?? 'IXO'}`;\n return checkRequiredURL(value, 'Logo is required or a valid URL');\n },\n }),\n coverImage: ({ results }) =>\n p.text({\n message: 'What is the cover image of the profile?',\n initialValue: results.logo as string,\n defaultValue: results.logo as string,\n validate(value) {\n if (!value) return results.logo as string;\n return checkRequiredURL(value, 'Cover image is required or a valid URL');\n },\n }),\n location: () =>\n p.text({\n message: 'What is the location of your domain?',\n initialValue: 'New York, NY',\n validate(value) {\n return checkRequiredString(value, 'Location is required');\n },\n }),\n description: () =>\n p.text({\n message: 'What is the description of the entity (profile)?',\n initialValue: 'We are a company that helps you with daily tasks',\n validate(value) {\n return checkRequiredString(value, 'Description is required');\n },\n }),\n url: () =>\n p.text({\n message: 'What is the website URL of the oracle? (optional, press Enter to skip)',\n placeholder: 'https://your-oracle-website.com',\n }),\n }),\n parentProtocol: () =>\n p.select({\n message: 'What is the parent protocol of the entity?',\n options: [\n {\n value: 'did:ixo:entity:1a76366f16570483cea72b111b27fd78',\n label: 'IXO Oracle Protocol',\n hint: 'default protocol',\n },\n ],\n initialValue: 'did:ixo:entity:1a76366f16570483cea72b111b27fd78',\n }),\n apiUrl: () =>\n p.text({\n message: 'What is the API URL of the oracle?',\n initialValue: 'http://localhost:4000',\n validate(value) {\n return checkRequiredURL(value, 'API URL is required or a valid URL');\n },\n }),\n },\n {\n // On Cancel callback that wraps the group\n // So if the user cancels one of the prompts in the group this function will be called\n onCancel: () => {\n p.cancel('Operation cancelled.');\n process.exit(0);\n },\n }\n );\n\n // Defer CreateEntity construction to execute() so matrixHomeServerUrl can be used\n const createEntity = new CreateEntity(this.wallet, this.config);\n\n const did = await createEntity.execute({\n oracleConfig: {\n oracleName: results.oracleName,\n price: parseInt(results.oraclePrice),\n },\n profile: {\n orgName: results.profile.orgName,\n name: results.profile.name,\n logo: results.profile.logo as string,\n coverImage: results.profile.coverImage as string,\n location: results.profile.location,\n description: results.profile.description,\n ...(results.profile.url ? { url: results.profile.url } : {}),\n },\n services: [\n {\n id: '{id}#api',\n serviceEndpoint: results.apiUrl,\n type: 'oracleService',\n },\n {\n id: '{id}#ws',\n serviceEndpoint: results.apiUrl,\n type: 'wsService',\n },\n ],\n parentProtocol: results.parentProtocol,\n matrixHomeServerUrl: results.matrixHomeServerUrl,\n });\n\n p.log.info(`API for the oracle is: ${results.apiUrl} | You can change this after you deploy the oracle`);\n\n // add to portal\n const portalBaseUrl = PORTAL_URL[(this.config.getValue('network') as NETWORK) ?? 'devnet'];\n\n const portalUrl = `${portalBaseUrl}/oracle/${did}/overview`;\n\n p.log.info(`Oracle created successfully: ${did}`);\n p.log.info(`Oracle URL: ${portalUrl}`);\n\n return {\n success: true,\n data: `Entity created successfully: ${did}`,\n };\n }\n}\n","import { select } from \"@clack/prompts\";\nimport { NETWORK } from \"@ixo/signx-sdk/types/types/transact\";\nimport { z } from \"zod\";\nimport { RuntimeConfig } from \"./runtime-config\";\n\nexport const selectNetwork = async (config: RuntimeConfig) => {\n const network = await select({\n message: \"Select network: (default: devnet)\",\n options: [\n { value: \"mainnet\", label: \"Mainnet\" },\n { value: \"testnet\", label: \"Testnet\" },\n { value: \"devnet\", label: \"Devnet\" },\n ],\n initialValue: \"devnet\",\n maxItems: 1,\n });\n\n config.addValue(\"network\", network as NETWORK);\n\n return network as NETWORK;\n};\n\nexport const RELAYER_NODE_DID = {\n mainnet: \"did:ixo:entity:2f22535f8b179a51d77a0e302e68d35d\",\n testnet: \"did:ixo:entity:3d079ebc0b332aad3305bb4a51c72edb\",\n devnet: \"did:ixo:entity:2f22535f8b179a51d77a0e302e68d35d\",\n};\n\nexport const MatrixHomeServerUrl: Record<NETWORK, string> = {\n devnet: \"https://devmx.ixo.earth\",\n testnet: \"https://testmx.ixo.earth\",\n mainnet: \"https://mx.ixo.earth\",\n};\n\nexport const MatrixRoomBotServerUrl: Record<NETWORK, string> = {\n devnet: \"https://rooms.bot.devmx.ixo.earth\",\n testnet: \"https://rooms.bot.testmx.ixo.earth\",\n mainnet: \"https://rooms.bot.mx.ixo.earth\",\n};\n\nexport const MatrixBotHomeServerUrl: Record<NETWORK, string> = {\n devnet: \"https://state.bot.devmx.ixo.earth\",\n testnet: \"https://state.bot.testmx.ixo.earth\",\n mainnet: \"https://state.bot.mx.ixo.earth\",\n};\nexport const PORTAL_URL = {\n devnet: \"https://ixo-portal.vercel.app\",\n testnet: \"https://ixo-portal.vercel.app\",\n mainnet: \"https://ixo-portal.vercel.app\",\n};\n\nexport const CHAIN_RPC = {\n mainnet: \"https://impacthub.ixo.world/rpc/\",\n testnet: \"https://testnet.ixo.earth/rpc/\",\n devnet: \"https://devnet.ixo.earth/rpc/\",\n};\n\nexport const DOMAIN_INDEXER_URL: Record<NETWORK, string> = {\n devnet: \"https://domain-indexer.devnet.ixo.earth/index\",\n testnet: \"https://domain-indexer.testnet.ixo.earth/index\",\n mainnet: \"https://domain-indexer.ixo.earth/index\",\n};\nexport const BLOCKSYNC_GRAPHQL_URL: Record<NETWORK, string> = {\n devnet: 'https://devnet-blocksync-graphql.ixo.earth/graphql',\n testnet: 'https://testnet-blocksync-graphql.ixo.earth/graphql',\n mainnet: 'https://blocksync-graphql.ixo.earth/graphql',\n};\n\nexport const MEMORY_ENGINE_API = {\n devnet: \"https://mcp-memory-engine.devnet.ixo.earth/\",\n testnet: \"https://memory-engine.testnet.ixo.earth/\",\n mainnet: \"https://memory-engine.ixo.earth/\",\n};\nexport const MEMORY_ENGINE_MCP = {\n devnet: \"https://mcp-memory-engine.devnet.ixo.earth/\",\n testnet: \"https://mcp-memory-engine.testnet.ixo.earth/\",\n mainnet: \"https://mcp-memory-engine.ixo.earth/\",\n};\n\nexport const SANDBOX_API = {\n devnet: \"https://ai-sandbox-devnet.ixo.earth/mcp\",\n testnet: \"https://ai-sandbox-testnet.ixo.earth/mcp\",\n mainnet: \"https://ai-sandbox.ixo.earth/mcp\",\n};\nexport const SUBSCRIPTION_API = {\n devnet: \"https://subscriptions-api.ixo-api.workers.dev\",\n testnet: \"https://subscriptions-api-testnet.ixo-api.workers.dev/\",\n mainnet: \"https://subscriptions-api-mainnet.ixo-api.workers.dev/\",\n};\nexport const checkRequiredString = (\n value: string | undefined,\n message = \"This field is required\",\n) => {\n const schema = z.string().min(1, message);\n const result = schema.safeParse(value);\n if (!result.success) {\n return result.error.message;\n }\n return undefined;\n};\n\nexport const checkIsEntityDid = (value: string | undefined) => {\n const schema = z\n .string()\n .regex(/^did:ixo:entity:[a-f0-9]{32}$/, \"Invalid entity DID\");\n const result = schema.safeParse(value);\n if (!result.success) {\n return result.error.message;\n }\n return undefined;\n};\n\nexport const checkRequiredURL = (\n value: string | undefined,\n message = \"This url is required or a valid URL\",\n) => {\n const schema = z.url(message);\n const result = schema.safeParse(value);\n if (!result.success) {\n return result.error.message;\n }\n return undefined;\n};\n\nexport const checkRequiredNumber = (\n value: number,\n message = \"This number is required\",\n) => {\n const schema = z.number().min(1, message);\n const result = schema.safeParse(value);\n if (!result.success) {\n return result.error.message;\n }\n return undefined;\n};\n\nexport const checkRequiredPin = (value: string | undefined) => {\n const schema = z\n .string()\n .min(1, \"PIN is required\")\n .refine((v) => /^\\d{6}$/.test(v), \"PIN must be exactly 6 digits\");\n const result = schema.safeParse(value);\n if (!result.success) {\n return result.error.issues[0]?.message ?? \"Invalid PIN\";\n }\n return undefined;\n};\n\nexport const checkRequiredMatrixUrl = (value: string | undefined) => {\n const schema = z\n .string()\n .min(1, \"Matrix homeserver URL is required\")\n .refine(\n (v) => /^https?:\\/\\//.test(v),\n \"Must start with http:// or https://\",\n )\n .refine((v) => !v.endsWith(\"/\"), \"Must not end with a trailing slash\");\n const result = schema.safeParse(value);\n if (!result.success) {\n return result.error.issues[0]?.message ?? \"Invalid Matrix URL\";\n }\n return undefined;\n};\n\nexport interface MatrixUrls {\n homeServerUrl: string;\n roomBotUrl: string;\n stateBotUrl: string;\n bidsBotUrl: string;\n claimsBotUrl: string;\n}\n\n/**\n * Derives all Matrix bot URLs from a homeserver URL using subdomain convention.\n * e.g. https://devmx.ixo.earth → https://rooms.bot.devmx.ixo.earth\n */\nexport function deriveMatrixUrls(homeServerUrl: string): MatrixUrls {\n const url = new URL(homeServerUrl);\n const domain = url.hostname;\n const protocol = url.protocol;\n\n return {\n homeServerUrl,\n roomBotUrl: `${protocol}//rooms.bot.${domain}`,\n stateBotUrl: `${protocol}//state.bot.${domain}`,\n bidsBotUrl: `${protocol}//bids.bot.${domain}`,\n claimsBotUrl: `${protocol}//claims.bot.${domain}`,\n };\n}\n","import { isCancel, log, spinner, text } from '@clack/prompts';\nimport { customMessages, ixo, utils } from '@ixo/impactxclient-sdk';\nimport { LinkedResource, Service } from '@ixo/impactxclient-sdk/types/codegen/ixo/iid/v1beta1/types';\nimport { NETWORK } from '@ixo/signx-sdk/types/types/transact';\nimport { logoutMatrixClient } from './account/matrix';\nimport { registerUserSimplified, SimplifiedRegistrationResult } from './account/simplifiedRegistration';\nimport { checkRequiredPin, DOMAIN_INDEXER_URL, RELAYER_NODE_DID } from './common';\nimport { publicUpload } from './matrix/upload-to-matrix';\nimport { RuntimeConfig } from './runtime-config';\nimport { Wallet } from './wallet';\n\ninterface CreateEntityParams {\n profile: {\n orgName: string;\n name: string;\n logo: string;\n coverImage: string;\n location: string;\n description: string;\n url?: string;\n };\n services: Service[];\n parentProtocol: string;\n oracleConfig: {\n oracleName: string;\n price: number;\n };\n matrixHomeServerUrl: string;\n}\ntype Denom = 'uixo' | 'ibc/6BBE9BD4246F8E04948D5A4EEE7164B2630263B9EBB5E7DC5F0A46C62A2FF97B';\n\nexport class CreateEntity {\n private readonly wallet: Wallet;\n constructor(wallet: Wallet, private config: RuntimeConfig) {\n if (!wallet.did || !wallet.pubKey || !wallet.address || !wallet.algo) {\n throw new Error('Wallet not found');\n }\n this.wallet = wallet;\n }\n\n private buildMsgCreateEntity(matrixHomeServerUrl: string) {\n const msg = {\n typeUrl: '/ixo.entity.v1beta1.MsgCreateEntity',\n value: ixo.entity.v1beta1.MsgCreateEntity.fromPartial({\n entityType: 'oracle',\n context: [],\n entityStatus: 0,\n verification: [\n ...customMessages.iid.createIidVerificationMethods({\n did: this.wallet.did!,\n pubkey: new Uint8Array(Buffer.from(this.wallet.pubKey!)),\n address: this.wallet.address!,\n controller: this.wallet.did!,\n type: this.wallet.algo === 'ed25519' ? 'ed' : 'secp',\n }),\n ],\n controller: [this.wallet.did!],\n ownerAddress: this.wallet.address!,\n ownerDid: this.wallet.did!,\n relayerNode: RELAYER_NODE_DID[(this.config.getValue('network') as NETWORK) ?? 'devnet'],\n service: [\n ixo.iid.v1beta1.Service.fromPartial({\n id: '{id}#matrix',\n type: 'MatrixHomeServer',\n serviceEndpoint: matrixHomeServerUrl,\n }),\n ],\n linkedResource: [],\n accordedRight: [],\n linkedEntity: [],\n linkedClaim: [],\n startDate: utils.proto.toTimestamp(new Date()),\n endDate: utils.proto.toTimestamp(new Date(Date.now() + 100 * 365 * 24 * 60 * 60 * 1000)),\n }),\n };\n return msg;\n }\n\n public addLinkedAccounts(\n msg: ReturnType<typeof this.buildMsgCreateEntity>,\n { oracleAccountAddress }: { oracleAccountAddress: string }\n ) {\n if (!this.wallet.signXClient || !this.wallet.wallet) {\n throw new Error('SignX client or wallet not found');\n }\n const memoryEngineByNetwork = {\n devnet: 'did:ixo:ixo17w9u5uk4qjyjgeyqfpnp92jwy58faey9vvp3ar',\n testnet: 'did:ixo:ixo14vjrckltpngugp03tcasfgh5qakey9n3sgm6y2',\n mainnet: 'did:ixo:ixo1d39eutxdc0e8mnp0fmzqjdy6aaf26s9hzrk33r',\n }[this.config.getValue('network') as NETWORK];\n\n const accounts = [memoryEngineByNetwork, `did:ixo:${oracleAccountAddress}`];\n const linkedAccounts = accounts.map((account) =>\n ixo.iid.v1beta1.LinkedEntity.fromPartial({\n id: account,\n type: 'agent',\n relationship: 'admin',\n service: 'matrix',\n })\n );\n\n msg.value.linkedEntity = linkedAccounts;\n }\n\n private async createAuthZConfig({\n oracleAccountAddress,\n oracleName,\n entityDid,\n homeServerUrl,\n accessToken,\n }: {\n oracleAccountAddress: string;\n oracleName: string;\n entityDid: string;\n homeServerUrl: string;\n accessToken: string;\n }): Promise<LinkedResource> {\n const config = {\n '@context': [\n 'https://schema.org',\n {\n ixo: 'https://w3id.org/ixo/context/v1',\n oracle: {\n '@id': entityDid,\n '@type': '@id',\n },\n },\n ],\n '@type': 'Service',\n '@id': 'oracle:OracleAuthorization',\n name: 'OracleAuthorization',\n description: 'OracleAuthorization',\n serviceType: 'OracleClaimAuthorizationService',\n requiredPermissions: ['/ixo.claims.v1beta1.MsgCreateClaimAuthorization'],\n granteeAddress: oracleAccountAddress,\n granterAddress: '',\n oracleName: oracleName,\n };\n const response = await publicUpload({\n data: config,\n fileName: 'authz',\n homeServerUrl,\n accessToken,\n });\n\n return ixo.iid.v1beta1.LinkedResource.fromPartial({\n id: '{id}#orz',\n type: 'oracleAuthZConfig',\n proof: response.proof,\n right: '',\n encrypted: 'false',\n mediaType: 'application/json',\n description: 'Orale AuthZ Config',\n serviceEndpoint: response.serviceEndpoint,\n });\n }\n\n private async createFeesConfig({\n entityDid,\n price,\n denom,\n homeServerUrl,\n accessToken,\n }: {\n entityDid: string;\n price: number;\n denom: Denom;\n homeServerUrl: string;\n accessToken: string;\n }): Promise<LinkedResource> {\n const config = {\n '@context': [\n 'https://schema.org',\n {\n ixo: 'https://w3id.org/ixo/context/v1',\n oracle: {\n '@id': entityDid,\n '@type': '@id',\n },\n },\n ],\n '@type': 'Service',\n '@id': 'oracle:ServiceFeeModel',\n name: 'Pricing',\n description: 'Pricing',\n serviceType: '',\n offers: {\n '@type': 'Offer',\n priceCurrency: denom,\n priceSpecification: {\n '@type': 'PaymentChargeSpecification',\n priceCurrency: denom,\n price: price * 1000, // 1 credit is 1000 uixo\n unitCode: 'MON',\n billingIncrement: 1,\n billingPeriod: 'P1M',\n priceType: 'Subscription',\n maxPrice: price,\n },\n eligibleQuantity: {\n '@type': 'QuantitativeValue',\n value: 1,\n unitCode: 'MON',\n },\n },\n };\n const response = await publicUpload({\n data: config,\n fileName: 'fees',\n homeServerUrl,\n accessToken,\n });\n return ixo.iid.v1beta1.LinkedResource.fromPartial({\n id: '{id}#fee',\n type: 'pricingList',\n proof: response.proof,\n right: '',\n encrypted: 'false',\n mediaType: 'application/json',\n description: 'Pricing List',\n serviceEndpoint: response.serviceEndpoint,\n });\n }\n\n /**\n * Update the oracle domain (API URL) services on an existing entity.\n * Deletes the old #api and #ws services, then adds new ones with the updated URL.\n */\n public async updateOracleDomain(entityDid: string, newApiUrl: string): Promise<void> {\n const walletAddress = this.wallet.wallet?.address;\n\n if (!this.wallet.signXClient || !this.wallet.wallet || !walletAddress) {\n throw new Error('SignX client or wallet not found');\n }\n\n const deleteApiMsg = {\n typeUrl: '/ixo.iid.v1beta1.MsgDeleteService',\n value: ixo.iid.v1beta1.MsgDeleteService.fromPartial({\n id: entityDid,\n serviceId: `${entityDid}#api`,\n signer: walletAddress,\n }),\n };\n\n const deleteWsMsg = {\n typeUrl: '/ixo.iid.v1beta1.MsgDeleteService',\n value: ixo.iid.v1beta1.MsgDeleteService.fromPartial({\n id: entityDid,\n serviceId: `${entityDid}#ws`,\n signer: walletAddress,\n }),\n };\n\n const addApiMsg = {\n typeUrl: '/ixo.iid.v1beta1.MsgAddService',\n value: ixo.iid.v1beta1.MsgAddService.fromPartial({\n id: entityDid,\n serviceData: ixo.iid.v1beta1.Service.fromPartial({\n id: `${entityDid}#api`,\n type: 'oracleService',\n serviceEndpoint: newApiUrl,\n }),\n signer: walletAddress,\n }),\n };\n\n const addWsMsg = {\n typeUrl: '/ixo.iid.v1beta1.MsgAddService',\n value: ixo.iid.v1beta1.MsgAddService.fromPartial({\n id: entityDid,\n serviceData: ixo.iid.v1beta1.Service.fromPartial({\n id: `${entityDid}#ws`,\n type: 'wsService',\n serviceEndpoint: newApiUrl,\n }),\n signer: walletAddress,\n }),\n };\n\n log.info(`Sign to update oracle domain for entity ${entityDid}`);\n const tx = await this.wallet.signXClient.transact(\n [deleteApiMsg, deleteWsMsg, addApiMsg, addWsMsg],\n this.wallet.wallet\n );\n this.wallet.signXClient.displayTransactionQRCode(JSON.stringify(tx));\n await this.wallet.signXClient.pollNextTransaction();\n await this.wallet.signXClient.awaitTransaction();\n log.success(`Oracle domain updated to ${newApiUrl}`);\n }\n\n /**\n * Add a controller to an existing entity\n */\n public async addControllerToEntity(entityDid: string, controllerDid: string): Promise<void> {\n const walletAddress = this.wallet.wallet?.address;\n\n if (!this.wallet.signXClient || !this.wallet.wallet || !walletAddress) {\n throw new Error('SignX client or wallet not found');\n }\n\n const addControllerMsg = {\n typeUrl: '/ixo.iid.v1beta1.MsgAddController',\n value: ixo.iid.v1beta1.MsgAddController.fromPartial({\n id: entityDid,\n controllerDid: controllerDid,\n signer: walletAddress,\n }),\n };\n\n log.info(`Sign to add controller ${controllerDid} to entity ${entityDid}`);\n const tx = await this.wallet.signXClient.transact([addControllerMsg], this.wallet.wallet);\n this.wallet.signXClient.displayTransactionQRCode(JSON.stringify(tx));\n await this.wallet.signXClient.pollNextTransaction();\n await this.wallet.signXClient.awaitTransaction();\n log.success(`Controller ${controllerDid} added to entity ${entityDid}`);\n }\n\n private async createOracleConfigFiles({\n oracleName,\n entityDid,\n price,\n oracleAccountAddress,\n homeServerUrl,\n accessToken,\n }: CreateEntityParams['oracleConfig'] & {\n entityDid: string;\n oracleAccountAddress: string;\n homeServerUrl: string;\n accessToken: string;\n }) {\n const walletAddress = this.wallet.wallet?.address;\n\n if (!this.wallet.signXClient || !this.wallet.wallet || !walletAddress) {\n throw new Error('SignX client or wallet not found');\n }\n\n const resources = await Promise.all([\n this.createAuthZConfig({\n oracleName,\n entityDid,\n oracleAccountAddress,\n homeServerUrl,\n accessToken,\n }),\n this.createFeesConfig({\n entityDid,\n price,\n denom:\n this.config.getValue('network') === 'devnet'\n ? 'uixo'\n : 'ibc/6BBE9BD4246F8E04948D5A4EEE7164B2630263B9EBB5E7DC5F0A46C62A2FF97B',\n homeServerUrl,\n accessToken,\n }),\n ]);\n const linkedResourcesMsgs = resources.map((resource) => ({\n typeUrl: '/ixo.iid.v1beta1.MsgAddLinkedResource',\n value: ixo.iid.v1beta1.MsgAddLinkedResource.fromPartial({\n id: entityDid,\n linkedResource: ixo.iid.v1beta1.LinkedResource.fromPartial({\n id: resource.id,\n description: resource.description,\n type: resource.type,\n proof: resource.proof,\n mediaType: resource.mediaType,\n encrypted: resource.encrypted,\n serviceEndpoint: resource.serviceEndpoint,\n }),\n signer: walletAddress,\n }),\n }));\n\n // sign and send the msgs\n log.info('Sign to edit the entity and add the config files');\n const tx = await this.wallet.signXClient.transact(linkedResourcesMsgs, this.wallet.wallet);\n this.wallet.signXClient.displayTransactionQRCode(JSON.stringify(tx));\n await this.wallet.signXClient.pollNextTransaction();\n const response = await this.wallet.signXClient.awaitTransaction();\n return response;\n }\n\n private async createDomainCard({\n profile,\n entityDid,\n homeServerUrl,\n accessToken,\n }: {\n profile: CreateEntityParams['profile'];\n entityDid: string;\n homeServerUrl: string;\n accessToken: string;\n }): Promise<LinkedResource> {\n const validFrom = new Date().toISOString();\n\n const domainCard = {\n '@context': [\n 'https://www.w3.org/ns/credentials/v2',\n 'https://w3id.org/ixo/context/v1',\n {\n schema: 'https://schema.org/',\n ixo: 'https://w3id.org/ixo/vocab/v1',\n prov: 'http://www.w3.org/ns/prov#',\n proj: 'https://linked.data.gov.au/def/project#',\n xsd: 'http://www.w3.org/2001/XMLSchema#',\n id: '@id',\n type: '@type',\n 'ixo:vector': {\n '@container': '@list',\n '@type': 'xsd:double',\n },\n '@protected': true,\n },\n ],\n id: `${entityDid}#dmn`,\n type: ['VerifiableCredential', 'ixo:DomainCard'],\n issuer: {\n id: this.wallet.did,\n },\n validFrom: validFrom,\n credentialSchema: {\n id: 'https://github.com/ixoworld/domainCards/schemas/ixo-domain-card-1.json',\n type: 'JsonSchema',\n },\n credentialSubject: {\n id: entityDid,\n type: ['ixo:oracle'],\n additionalType: ['schema:Organization'],\n name: profile.name,\n alternateName: profile.orgName !== profile.name ? [profile.orgName] : undefined,\n description: profile.description,\n logo: {\n type: 'schema:ImageObject',\n id: profile.logo,\n contentUrl: profile.logo,\n },\n image: [\n {\n type: 'schema:ImageObject',\n id: profile.coverImage,\n contentUrl: profile.coverImage,\n },\n ],\n address: {\n type: 'schema:PostalAddress',\n addressLocality: profile.location,\n },\n ...(profile.url ? { url: profile.url } : {}),\n },\n };\n\n const response = await publicUpload({\n data: domainCard,\n fileName: 'domainCard',\n homeServerUrl,\n accessToken,\n });\n\n return ixo.iid.v1beta1.LinkedResource.fromPartial({\n id: '{id}#dmn',\n type: 'domainCard',\n proof: response.proof,\n right: '',\n encrypted: 'false',\n mediaType: 'application/json',\n description: 'Domain Card',\n serviceEndpoint: response.serviceEndpoint,\n });\n }\n\n private async addProfile({\n orgName,\n name,\n logo,\n coverImage,\n location,\n description,\n homeServerUrl,\n accessToken,\n }: CreateEntityParams['profile'] & { homeServerUrl: string; accessToken: string }) {\n const profileData = {\n '@context': {\n ixo: 'https://w3id.org/ixo/ns/protocol/',\n '@id': '@type',\n type: '@type',\n '@protected': false,\n },\n id: 'ixo:entity#profile',\n type: 'profile',\n orgName,\n name,\n image: coverImage,\n logo,\n brand: orgName,\n location,\n description,\n };\n\n const response = await publicUpload({\n data: profileData,\n fileName: 'profile',\n homeServerUrl,\n accessToken,\n });\n\n return ixo.iid.v1beta1.LinkedResource.fromPartial({\n id: '{id}#pro',\n type: 'Settings',\n description: 'Profile',\n mediaType: 'application/json',\n serviceEndpoint: response.serviceEndpoint,\n proof: response.proof,\n encrypted: 'false',\n right: '',\n });\n }\n\n private addServices(msg: ReturnType<typeof this.buildMsgCreateEntity>, services: Service[]) {\n msg.value.service.push(...services.map((service) => ixo.iid.v1beta1.Service.fromPartial(service)));\n }\n\n private setParentProtocol(msg: ReturnType<typeof this.buildMsgCreateEntity>, parentProtocol: string) {\n msg.value.context.push(\n ...customMessages.iid.createAgentIidContext([{ key: 'class', val: parentProtocol }])\n );\n }\n\n private async submitToDomainIndexer(entityDid: string): Promise<void> {\n const network = (this.config.getValue('network') as NETWORK) ?? 'devnet';\n const indexerUrl = DOMAIN_INDEXER_URL[network];\n\n try {\n const response = await fetch(indexerUrl, {\n method: 'POST',\n headers: {\n accept: 'application/json',\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n did: entityDid,\n }),\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n log.warn(`Failed to submit to domain indexer: ${response.status} ${errorText}`);\n return;\n }\n\n log.success('Domain card submitted to domain indexer');\n } catch (error) {\n log.warn(`Error submitting to domain indexer: ${error instanceof Error ? error.message : String(error)}`);\n }\n }\n\n public async execute(params: CreateEntityParams): Promise<string> {\n if (!this.wallet.signXClient || !this.wallet.wallet) {\n throw new Error('SignX client not found');\n }\n\n const { matrixHomeServerUrl } = params;\n\n // =================================================================================================\n // 1. REGISTER ORACLE FIRST — we need oracle's credentials for uploads\n // =================================================================================================\n log.info('Creating Oracle Wallet and Matrix Account');\n const pin = await text({\n message: 'Enter a 6-digit PIN to secure your Matrix Vault:',\n placeholder: '123456',\n validate(value) {\n return checkRequiredPin(value);\n },\n });\n if (isCancel(pin)) {\n log.error('User cancelled');\n process.exit(1);\n }\n const registerResult = await registerUserSimplified(\n {\n pin,\n oracleName: params.oracleConfig.oracleName,\n network: this.config.getValue('network') as NETWORK,\n oracleAvatarUrl: params.profile.logo,\n matrixHomeServerUrl,\n },\n async (address) => {\n await this.wallet.sendTokens(address, 250_000); // 250,000 uixo = 0.25 IXO;\n }\n );\n\n // Oracle's credentials for uploading to oracle's Matrix server\n const oracleHomeServerUrl = registerResult.matrixHomeServerUrl;\n const oracleAccessToken = registerResult.matrixAccessToken;\n\n // =================================================================================================\n // 2. UPLOAD PROFILE using oracle's credentials\n // =================================================================================================\n log.info('Adding profile');\n const profileResource = await this.addProfile({\n ...params.profile,\n homeServerUrl: oracleHomeServerUrl,\n accessToken: oracleAccessToken,\n });\n\n // =================================================================================================\n // 3. BUILD AND BROADCAST MsgCreateEntity\n // =================================================================================================\n const msg = this.buildMsgCreateEntity(matrixHomeServerUrl);\n\n // Add profile linked resource\n msg.value.linkedResource.push(profileResource);\n\n // Add services\n log.info('Adding services');\n this.addServices(msg, params.services);\n\n // Add parent protocol\n log.info('Adding parent protocol');\n this.setParentProtocol(msg, params.parentProtocol);\n\n // Add linked accounts\n this.addLinkedAccounts(msg, {\n oracleAccountAddress: registerResult.address,\n });\n\n log.info('Sign this transaction to create the entity');\n const tx = await this.wallet.signXClient.transact([msg], this.wallet.wallet);\n this.wallet.signXClient.displayTransactionQRCode(JSON.stringify(tx));\n await this.wallet.signXClient.pollNextTransaction();\n\n // Wait for transaction completion\n const response = await this.wallet.signXClient.awaitTransaction();\n log.success('Entity created -- wait to attach the required config files');\n\n // upload resources\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const did = utils.common.getValueFromEvents(response as any, 'wasm', 'token_id');\n\n // =================================================================================================\n // 4. CREATE AND ATTACH DOMAIN CARD using oracle's credentials\n // =================================================================================================\n log.info('Creating domain card');\n const domainCardResource = await this.createDomainCard({\n profile: params.profile,\n entityDid: did,\n homeServerUrl: oracleHomeServerUrl,\n accessToken: oracleAccessToken,\n });\n\n // Add domain card to entity\n if (this.wallet.wallet?.address) {\n const addDomainCardMsg = {\n typeUrl: '/ixo.iid.v1beta1.MsgAddLinkedResource',\n value: ixo.iid.v1beta1.MsgAddLinkedResource.fromPartial({\n id: did,\n linkedResource: ixo.iid.v1beta1.LinkedResource.fromPartial({\n id: domainCardResource.id,\n description: domainCardResource.description,\n type: domainCardResource.type,\n proof: domainCardResource.proof,\n mediaType: domainCardResource.mediaType,\n encrypted: domainCardResource.encrypted,\n serviceEndpoint: domainCardResource.serviceEndpoint,\n }),\n signer: this.wallet.wallet.address,\n }),\n };\n log.info('Sign to add domain card to the entity');\n const domainCardTx = await this.wallet.signXClient.transact([addDomainCardMsg], this.wallet.wallet);\n this.wallet.signXClient.displayTransactionQRCode(JSON.stringify(domainCardTx));\n await this.wallet.signXClient.pollNextTransaction();\n await this.wallet.signXClient.awaitTransaction();\n log.success('Domain card added to entity');\n }\n\n // =================================================================================================\n // 5. CREATE AND ATTACH CONFIG FILES using oracle's credentials\n // =================================================================================================\n await this.createOracleConfigFiles({\n oracleName: params.oracleConfig.oracleName,\n price: params.oracleConfig.price,\n oracleAccountAddress: registerResult.address,\n entityDid: did,\n homeServerUrl: oracleHomeServerUrl,\n accessToken: oracleAccessToken,\n });\n log.success('Entity created -- config files attached');\n\n // =================================================================================================\n // 6. LOGOUT ORACLE's Matrix session (no longer needed)\n // =================================================================================================\n await logoutMatrixClient({\n baseUrl: oracleHomeServerUrl,\n accessToken: oracleAccessToken,\n userId: registerResult.matrixUserId,\n deviceId: '',\n });\n\n const s = spinner();\n s.start('Creating Entity Matrix Room...');\n s.stop('Room created -- room joined');\n log.warn('Please save the following information in a secure location as it is not stored:');\n log.info(`ORACLE ACCOUNT DETAILS`);\n\n for (const key in registerResult) {\n log.info(`${key}: ${registerResult[key as keyof SimplifiedRegistrationResult]}`);\n }\n this.config.addValue('registerUserResult', registerResult);\n this.config.addValue('entityDid', did);\n this.config.addValue('oracleMatrixHomeServerUrl', matrixHomeServerUrl);\n\n // Submit to domain indexer\n log.info('Submitting domain card to domain indexer');\n await this.submitToDomainIndexer(did);\n\n return did;\n }\n}\n","import { sha256 } from '@cosmjs/crypto';\nimport { encrypt as eciesEncrypt } from 'eciesjs';\nimport { ClientEvent, createClient, MatrixClient } from 'matrix-js-sdk';\nimport { CryptoApi } from 'matrix-js-sdk/lib/crypto-api';\nimport md5 from 'md5';\n\n// import cons from '@constants/matrix';\n// import { isAuthenticated, secret } from '@utils/secrets';\nimport { cacheSecretStorageKey, clearSecretStorageKeys, getSecretStorageKey } from './secretStorageKeys';\nimport { delay } from './utils';\n\nconst WELL_KNOWN_URI = '/.well-known/matrix/client';\n\n// =================================================================================================\n// AUTH\n// =================================================================================================\ninterface AuthResponse {\n accessToken: string;\n deviceId: string;\n userId: string;\n baseUrl: string;\n}\nexport const mxLogin = async (\n {\n homeServerUrl,\n username,\n password,\n deviceName,\n }: { homeServerUrl: string; username: string; password: string; deviceName: string },\n localMatrix = false\n) => {\n let mxHomeServerUrl = homeServerUrl;\n let mxUsername = username;\n const mxIdMatch = mxUsername.match(/^@(.+):(.+\\..+)$/);\n if (mxIdMatch) {\n mxUsername = mxIdMatch[1] as string;\n mxHomeServerUrl = mxIdMatch[2] as string;\n mxHomeServerUrl = localMatrix ? mxHomeServerUrl : await getBaseUrl(mxHomeServerUrl);\n }\n\n try {\n const client = createTemporaryClient(mxHomeServerUrl);\n const response = await client.login('m.login.password', {\n identifier: {\n type: 'm.id.user',\n user: normalizeUsername(mxUsername),\n },\n password,\n initial_device_display_name: deviceName,\n });\n const data: AuthResponse = {\n accessToken: response.access_token,\n deviceId: response.device_id,\n userId: response.user_id,\n baseUrl: localMatrix ? mxHomeServerUrl : response?.well_known?.['m.homeserver']?.base_url || client.baseUrl,\n };\n return data;\n } catch (error) {\n let msg = (error as any).message;\n if (msg === 'Unknown message') {\n msg = 'Please check your credentials';\n }\n console.error(`mxLogin::`, msg);\n throw new Error(msg);\n }\n};\n\n// =================================================================================================\n// NEW API-BASED REGISTRATION\n// =================================================================================================\n\ninterface PublicKeyResponse {\n publicKey: string;\n fingerprint: string;\n algorithm: string;\n usage: string;\n}\n\ninterface UserCreationChallenge {\n timestamp: string;\n address: string;\n service: string;\n type: string;\n}\n\ninterface UserCreationRequest {\n address: string;\n encryptedPassword: string;\n publicKeyFingerprint: string;\n authnResult?: any;\n secpResult?: {\n signature: string;\n challenge: string;\n };\n}\n\ninterface UserCreationResponse {\n success: boolean;\n matrixUserId: string;\n address: string;\n message: string;\n}\n\n/**\n * Fetch the public key for password encryption from the user creation API\n * @returns Public key information for encryption\n */\nexport async function getPublicKeyForEncryption(roomBotUrl: string): Promise<PublicKeyResponse> {\n const response = await fetch(`${roomBotUrl}/public-key`, {\n method: 'GET',\n headers: {\n 'Content-Type': 'application/json',\n },\n });\n\n if (!response.ok) {\n throw new Error('Failed to fetch public key for encryption');\n }\n\n const data = (await response.json()) as PublicKeyResponse;\n return data;\n}\n\n/**\n * Create a structured challenge for user creation\n * @param address The user's address (without did:ixo: prefix)\n * @returns The challenge object and its base64 representation\n */\nexport function createUserCreationChallenge(address: string): {\n challenge: UserCreationChallenge;\n challengeBase64: string;\n} {\n const challenge: UserCreationChallenge = {\n timestamp: new Date().toISOString(),\n address: address,\n service: 'matrix',\n type: 'create-account',\n };\n\n const challengeBase64 = Buffer.from(JSON.stringify(challenge)).toString('base64');\n\n return { challenge, challengeBase64 };\n}\n\n/**\n * Encrypt password using ECIES with the provided public key\n * @param password The password to encrypt\n * @param publicKey The public key in hex format\n * @returns The encrypted password in hex format\n */\nexport function encryptPasswordWithECIES(password: string, publicKey: string): string {\n const publicKeyBytes = new Uint8Array(Buffer.from(publicKey, 'hex'));\n const passwordBytes = new Uint8Array(Buffer.from(password, 'utf8'));\n const encryptedPassword = eciesEncrypt(publicKeyBytes, passwordBytes);\n return Array.from(encryptedPassword, (byte) => byte.toString(16).padStart(2, '0')).join('');\n}\n\n/**\n * Create user account using secp256k1 signature authentication\n * @param address The user's address\n * @param password The matrix password\n * @param signature The secp256k1 signature (base64)\n * @param challenge The challenge that was signed (base64)\n * @returns The user creation response\n */\nexport async function createUserAccountWithSecp(\n address: string,\n password: string,\n signature: string,\n challenge: string,\n homeServerUrl: string,\n roomBotUrl: string\n): Promise<UserCreationResponse> {\n const publicKeyInfo = await getPublicKeyForEncryption(roomBotUrl);\n const encryptedPassword = encryptPasswordWithECIES(password, publicKeyInfo.publicKey);\n\n const request: UserCreationRequest = {\n address,\n encryptedPassword,\n publicKeyFingerprint: publicKeyInfo.fingerprint,\n secpResult: {\n signature,\n challenge,\n },\n };\n\n const response = await fetch(`${roomBotUrl}/user/create`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(request),\n });\n\n if (!response.ok) {\n const responseText = await response.text();\n let errorMessage = `Failed to create user account (HTTP ${response.status})`;\n try {\n const errorData = JSON.parse(responseText);\n errorMessage = errorData.error || errorData.message || errorData.detail || responseText;\n } catch {\n errorMessage = responseText || errorMessage;\n }\n console.error(`Room bot error [${response.status}]: ${responseText}`);\n throw new Error(errorMessage);\n }\n\n return (await response.json()) as UserCreationResponse;\n}\n\n// =================================================================================================\n// UPDATED REGISTRATION FUNCTIONS\n// =================================================================================================\n\n/**\n * Register matrix account using the new API with secp256k1 signature authentication\n * @param address The user's address\n * @param password The matrix password\n * @param deviceName The device name for the Matrix session\n * @param wallet The secp wallet for signing\n * @param homeServerUrl The Matrix homeserver URL\n * @param roomBotUrl The room bot URL\n * @returns AuthResponse with access token and user details\n */\nexport async function mxRegisterWithSecp(\n address: string,\n password: string,\n deviceName: string,\n wallet: { sign: (message: string) => Promise<Uint8Array> },\n homeServerUrl: string,\n roomBotUrl: string\n): Promise<AuthResponse> {\n try {\n // Create challenge and sign it\n const { challengeBase64 } = createUserCreationChallenge(address);\n const signatureBytes = await wallet.sign(challengeBase64);\n const signature = Buffer.from(signatureBytes).toString('base64');\n\n const userCreationResult = await createUserAccountWithSecp(\n address,\n password,\n signature,\n challengeBase64,\n homeServerUrl,\n roomBotUrl\n );\n\n if (!userCreationResult.success) {\n throw new Error('Failed to create matrix account via API');\n }\n\n const username = generateUsernameFromAddress(address);\n\n const loginResult = await mxLogin({\n homeServerUrl,\n username,\n password,\n deviceName,\n });\n\n return loginResult;\n } catch (error) {\n console.error('mxRegisterWithSecp error:', error);\n throw error;\n }\n}\n\nexport async function checkIsUsernameAvailable({\n homeServerUrl,\n username,\n}: {\n homeServerUrl: string;\n username: string;\n}) {\n const client = createTemporaryClient(homeServerUrl);\n try {\n const isUsernameAvailable = await client.isUsernameAvailable(username);\n return !!isUsernameAvailable;\n } catch (error) {\n return false;\n }\n}\n\n// =================================================================================================\n// CLIENT\n// =================================================================================================\n/**\n * Creates a temporary matrix client, used for matrix login or registration to get access tokens\n * @param homeServerUrl - the home server url to instantiate the matrix client\n * @returns matrix client\n */\nexport function createTemporaryClient(homeServerUrl: string) {\n if (!homeServerUrl) {\n throw new Error('Home server URL is required to instantiate matrix client');\n }\n return createClient({\n baseUrl: homeServerUrl,\n });\n}\n\nexport async function createMatrixClient({\n homeServerUrl,\n accessToken,\n userId,\n deviceId,\n}: {\n homeServerUrl: string;\n accessToken: string;\n userId: string;\n deviceId: string;\n}) {\n console.log('createMatrixClient::', { homeServerUrl, accessToken, userId, deviceId });\n\n if (!homeServerUrl || !accessToken || !userId || !deviceId) {\n throw new Error('Login to Matrix account before trying to instantiate Matrix client.');\n }\n\n // const indexedDBStore = new IndexedDBStore({\n // indexedDB: global.indexedDB,\n // dbName: 'matrix-sync-store',\n // });\n // const legacyCryptoStore = new IndexedDBCryptoStore()\n\n const mxClient = createClient({\n baseUrl: homeServerUrl,\n accessToken,\n userId,\n // store: indexedDBStore,\n // cryptoStore: legacyCryptoStore,\n deviceId,\n timelineSupport: true,\n cryptoCallbacks: {\n getSecretStorageKey: getSecretStorageKey,\n cacheSecretStorageKey: cacheSecretStorageKey,\n },\n verificationMethods: ['m.sas.v1'],\n });\n // await indexedDBStore.startup();\n await mxClient.initRustCrypto({\n useIndexedDB: false,\n });\n // mxClient.setGlobalErrorOnUnknownDevices(false);\n mxClient.setMaxListeners(20);\n // const filter = new Filter(userId);\n // filter.setDefinition({\n // room: {\n // state: {\n // lazy_load_members: true,\n // types: [],\n // },\n // timeline: {\n // types: [],\n // },\n // },\n // // Disable unnecessary features\n // presence: {\n // types: [], // No presence updates needed\n // },\n // account_data: {\n // types: ['m.cross_signing.master'], // No account data needed\n // },\n // });\n await mxClient.startClient({\n lazyLoadMembers: true,\n // initialSyncLimit: 1,\n includeArchivedRooms: false,\n // pollTimeout: 2 * 60 * 1000, // poll every 2 minutes\n // filter: filter,\n });\n await new Promise<void>((resolve, reject) => {\n const sync = {\n NULL: () => {\n console.info('[NULL] state');\n },\n SYNCING: () => {\n void 0;\n },\n PREPARED: () => {\n console.info(`[PREPARED] state: user ${userId}`);\n resolve();\n },\n RECONNECTING: () => {\n console.info('[RECONNECTING] state');\n },\n CATCHUP: () => {\n console.info('[CATCHUP] state');\n },\n ERROR: () => {\n reject(new Error('[ERROR] state: starting matrix client'));\n },\n STOPPED: () => {\n console.info('[STOPPED] state');\n },\n };\n mxClient.on(ClientEvent.Sync, (state) => {\n sync[state]();\n });\n });\n return mxClient;\n}\n\nexport async function logoutMatrixClient({\n mxClient,\n baseUrl,\n accessToken,\n userId,\n deviceId,\n}: {\n mxClient?: MatrixClient;\n baseUrl: string;\n accessToken: string;\n userId: string;\n deviceId: string;\n}) {\n let client = mxClient;\n if (!client) {\n client = createClient({\n baseUrl: baseUrl,\n accessToken,\n userId,\n deviceId,\n });\n }\n if (client) {\n client.stopClient();\n await client.logout().catch(console.error);\n client.clearStores();\n }\n}\n\n// =================================================================================================\n// CROSS SIGNING\n// =================================================================================================\n/**\n * Check if the user has cross-signing account data.\n * @param {MatrixClient} mxClient - The matrix client to check.\n * @returns {boolean} True if the user has cross-signing account data, otherwise false.\n */\nexport function hasCrossSigningAccountData(mxClient: MatrixClient): boolean {\n const masterKeyData = mxClient.getAccountData('m.cross_signing.master');\n console.log('hasCrossSigningAccountData::masterKeyData', masterKeyData);\n return !!masterKeyData;\n}\n\n/**\n * Setup cross signing and secret storage for the current user\n * @param {MatrixClient} mxClient - The matrix client to setup cross signing for\n * @param {string} securityPhrase - the security phrase to use for secret storage\n * @param {string} password - the password for the matrix account\n * @param {boolean} forceReset - if to force reset the cross signing keys (NB, only do if you know what you are doing!!!)\n * @param {boolean} skipBootstrapSS - if to skip bootstrapping secret storage\n * @returns {boolean} True if the cross signing was setup successfully, otherwise false.\n */\nexport async function setupCrossSigning(\n mxClient: MatrixClient,\n {\n securityPhrase,\n password,\n forceReset = false,\n skipBootstrapSecureStorage = false,\n }: { securityPhrase: string; password: string; forceReset?: boolean; skipBootstrapSecureStorage?: boolean }\n): Promise<boolean> {\n if (forceReset) {\n clearSecretStorageKeys();\n }\n\n const mxCrypto = mxClient.getCrypto() as CryptoApi;\n if (!mxCrypto) {\n throw new Error('Failed to setup matrix cross signing - failed to get matrix crypto api');\n }\n if (!skipBootstrapSecureStorage) {\n const recoveryKey = await mxCrypto.createRecoveryKeyFromPassphrase(securityPhrase);\n clearSecretStorageKeys();\n await mxCrypto.bootstrapSecretStorage({\n createSecretStorageKey: async () => recoveryKey!,\n setupNewSecretStorage: forceReset,\n });\n }\n const userId = mxClient.getUserId()!;\n await mxCrypto.bootstrapCrossSigning({\n authUploadDeviceSigningKeys: async function (makeRequest) {\n await makeRequest(getAuthId({ userId, password }));\n },\n setupNewCrossSigning: forceReset,\n });\n await mxCrypto.resetKeyBackup();\n\n await delay(300);\n\n return !!mxClient.getAccountData('m.cross_signing.master');\n}\n\n// =================================================================================================\n// GENERAL\n// =================================================================================================\n/**\n * Generates a username from an address, used for matrix login, generated an account did\n * @param {string} address - the address to generate the username from\n * @returns {string} username\n */\nexport function generateUsernameFromAddress(address: string): string {\n if (!address) {\n throw new Error('Address is required to generate matrix username');\n }\n return 'did-ixo-' + address;\n}\n\n/**\n * Generates a password from a mnemonic, used for matrix login, generated using the first 24 bytes of the base64 encoded md5 hash of the mnemonic\n * @param {string} mnemonic - the mnemonic to generate the password from\n * @returns {string} password\n */\nexport function generatePasswordFromMnemonic(mnemonic: string): string {\n const base64 = Buffer.from(md5(mnemonic.replace(/ /g, ''))).toString('base64');\n return base64.slice(0, 24);\n}\n\n/**\n * Generates a recovery phrase from a mnemonic, used for matrix recovery, generated using the first 32 bytes of the base64 encoded sha256 hash of the mnemonic\n * @param {string} mnemonic - the mnemonic to generate the recovery phrase from\n * @returns {string} recoveryPhrase\n */\nexport function generateRecoveryPhraseFromMnemonic(mnemonic: string): string {\n const hash = sha256(new TextEncoder().encode(mnemonic.replace(/ /g, '')));\n const base64 = Buffer.from(hash).toString('base64');\n return base64.slice(0, 32);\n}\n\n/**\n * Extracts the home server URL from a user ID.\n * @param {string} userId - The user ID to extract the homeserver URL from.\n * @returns {string} The homeserver URL.\n */\nexport function extractHomeServerUrlFromUserId(userId: string): string {\n const parts = userId.split(':');\n if (parts.length < 2) {\n throw new Error('Invalid userId');\n }\n return parts.slice(1).join(':');\n}\n\n/**\n * Generates a recovery phrase from a mnemonic, used for matrix recovery, generated using the first 32 bytes of the base64 encoded sha256 hash of the mnemonic\n * @param {string} mnemonic - the mnemonic to generate the recovery phrase from\n * @returns {string} passphrase\n */\nexport function generatePassphraseFromMnemonic(mnemonic: string): string {\n const hash = sha256(new TextEncoder().encode(mnemonic.replace(/ /g, '')));\n const base64 = Buffer.from(hash).toString('base64');\n return base64.slice(0, 32);\n}\n\n/**\n * Cleans a home server URL by removing protocol and trailing slashes\n * @param {string} homeServer - the homeserver URL to clean\n * @returns {string} cleaned homeserver URL\n */\nexport function cleanMatrixHomeServerUrl(homeServer: string): string {\n return homeServer.replace(/^(https?:\\/\\/)/, '').replace(/\\/$/, '');\n}\n\n/**\n * Generates a room name from an account address, used for matrix user room where user can manage their own data\n * @param {string} address - the address of the user\n * @param {string} postpend - the postpend of the room name (for testing)\n * @returns {string} roomName\n */\nexport function generateUserRoomNameFromAddress(address: string, postpend = ''): string {\n return 'did-ixo-' + address + postpend;\n}\n\n/**\n * Generates a room alias from an account address, used for matrix user room where user can manage their own data\n * @param {string} address - the address of the user\n * @param {string} postpend - the postpend of the room alias (for testing)\n * @returns {string} roomAlias\n */\nexport function generateUserRoomAliasFromAddress(address: string, homeServerUrl: string): string {\n return '#' + generateUserRoomNameFromAddress(address) + ':' + cleanMatrixHomeServerUrl(homeServerUrl);\n}\n\n/**\n * Get the base URL for a given servername.\n * @param servername The servername to get the base URL for.\n * @returns The base URL for the servername.\n */\nexport async function getBaseUrl(servername: string): Promise<string> {\n let protocol = 'https://';\n if (/^https?:\\/\\//.test(servername)) {\n protocol = '';\n }\n const serverDiscoveryUrl = `${protocol}${servername}${WELL_KNOWN_URI}`;\n try {\n const response = await fetch(serverDiscoveryUrl, { method: 'GET' });\n const result = await response.json();\n const baseUrl = (result as { 'm.homeserver': { base_url: string } })['m.homeserver']?.base_url;\n if (baseUrl === undefined) {\n throw new Error();\n }\n return baseUrl;\n } catch (e) {\n return `${protocol}${servername}`;\n }\n}\n\n/**\n * Normalize a username by removing leading '@' and trimming whitespace.\n * @param {string} rawUsername - The raw username to normalize.\n * @returns {string} The normalized username.\n */\nexport function normalizeUsername(rawUsername: string): string {\n const noLeadingAt = rawUsername.indexOf('@') === 0 ? rawUsername.substring(1) : rawUsername;\n return noLeadingAt.trim();\n}\n\n/**\n * Generates the authentication identifier for matrix login\n * @param {string} password - the password for the matrix account\n * @returns {object} authId - the authentication identifier\n */\nexport function getAuthId({ userId, password }: { userId: string; password: string }): {\n type: string;\n password: string;\n identifier: { type: string; user: string };\n} {\n return {\n type: 'm.login.password',\n password,\n identifier: {\n type: 'm.id.user',\n user: userId,\n },\n };\n}\n","const secretStorageKeys = new Map();\n\nexport function storePrivateKey(keyId: string, privateKey: Uint8Array) {\n if (privateKey instanceof Uint8Array === false) {\n throw new Error('Unable to store, privateKey is invalid.');\n }\n\n secretStorageKeys.set(keyId, privateKey);\n}\n\nexport function hasPrivateKey(keyId: string) {\n return secretStorageKeys.get(keyId) instanceof Uint8Array;\n}\n\nexport function getPrivateKey(keyId: string) {\n return secretStorageKeys.get(keyId);\n}\n\nexport function deletePrivateKey(keyId: string) {\n secretStorageKeys.delete(keyId);\n}\n\nexport function clearSecretStorageKeys() {\n secretStorageKeys.clear();\n}\n\nexport async function getSecretStorageKey({ keys }: { keys: any }): Promise<[string, Uint8Array] | null> {\n const keyIds = Object.keys(keys);\n const keyId = keyIds.find(hasPrivateKey);\n console.info('[] getSecretStorageKey', keys, keyIds, keyId);\n\n if (!keyId) {\n return null;\n }\n\n const privateKey = getPrivateKey(keyId);\n\n return [keyId, privateKey];\n}\n\nexport function cacheSecretStorageKey(keyId: string, keyInfo: any, privateKey: Uint8Array) {\n secretStorageKeys.set(keyId, privateKey);\n}\n","import { Bip39, EnglishMnemonic, Secp256k1, sha256, Slip10, Slip10Curve, stringToPath } from '@cosmjs/crypto';\nimport { AccountData, DirectSecp256k1HdWallet, OfflineSigner } from '@cosmjs/proto-signing';\nimport { createQueryClient, createSigningClient, customMessages, ixo, utils } from '@ixo/impactxclient-sdk';\nimport { Service } from '@ixo/impactxclient-sdk/types/codegen/ixo/iid/v1beta1/types';\nimport { NETWORK } from '@ixo/signx-sdk/types/types/transact';\nimport { createCipheriv, randomBytes } from 'crypto';\nimport { CHAIN_RPC } from '../common';\nimport { decodeGrants, isAllowanceExpired, isAllowanceLimitReached } from './feegrant';\n/**\n * Checks if an iid document (did) exists\n * @param did - The did to check for\n * @returns True if the iid document exists, false otherwise\n */\nexport async function checkIidDocumentExists(did: string, network: NETWORK) {\n if (!network) {\n throw new Error('Network parameter is required but was undefined');\n }\n\n console.log(`🔍 Checking IID document for DID: ${did} on network: ${network}`);\n\n const url = CHAIN_RPC[network];\n if (!url) {\n throw new Error(`Invalid network: ${network}. Valid networks are: ${Object.keys(CHAIN_RPC).join(', ')}`);\n }\n\n console.log(`🔗 Using RPC URL: ${url}`);\n\n try {\n const queryClient = await createQueryClient(url);\n const iidDocumentResponse = await queryClient.ixo.iid.v1beta1.iidDocument({ id: did });\n if (!iidDocumentResponse?.iidDocument?.id) {\n return false;\n }\n return true;\n } catch (error) {\n if ((error as Error).message?.includes('did document not found') || (error as Error).message?.includes('(22)')) {\n return false;\n }\n console.error('Error checking IID document:', error);\n throw error;\n }\n}\n\n/**\n * Creates an iid document (did)\n * Must be signed by base account mnemonic (not passkey signer)\n * @param did - The did to create iid document for\n * @param offlineSigner - The offline signer to use to create iid document\n */\nexport async function createIidDocument(\n did: string,\n network: NETWORK,\n offlineSigner: OfflineSigner,\n services?: Service[]\n) {\n try {\n const accounts = await offlineSigner.getAccounts();\n const { address, pubkey } = (accounts[0] ?? {}) as AccountData;\n const allowances = await queryAddressAllowances(address, network);\n const feegrantGranter = allowances?.length\n ? decodeGrants(allowances)?.find(\n (allowance) =>\n !!allowance &&\n !isAllowanceExpired(allowance.expiration as number) &&\n !isAllowanceLimitReached(allowance.limit)\n )?.granter\n : undefined;\n const trx = {\n typeUrl: '/ixo.iid.v1beta1.MsgCreateIidDocument',\n value: ixo.iid.v1beta1.MsgCreateIidDocument.fromPartial({\n id: did,\n verifications: customMessages.iid.createIidVerificationMethods({\n did: did,\n pubkey: pubkey,\n address: address,\n controller: did,\n type: 'secp',\n }),\n signer: address,\n controllers: [did],\n ...(services?.length ? { services: services } : {}),\n }),\n };\n // if (!feegrantGranter) {\n // throw new Error('No feegrant granter found');\n // }\n await signAndBroadcastWithMnemonic({\n offlineSigner: offlineSigner,\n messages: [trx],\n feegrantGranter: feegrantGranter as string,\n network,\n });\n } catch (error) {\n console.error(error);\n throw error;\n }\n}\n\nexport async function queryAddressAllowances(address: string, network: NETWORK) {\n try {\n const url = CHAIN_RPC[network];\n if (!url) {\n throw new Error(`Invalid network: ${network}`);\n }\n const queryClient = await createQueryClient(url);\n const allowancesResponse = await queryClient.cosmos.feegrant.v1beta1.allowances({\n grantee: address,\n });\n return allowancesResponse?.allowances ?? [];\n } catch (error) {\n console.error('queryAddressAllowances::', (error as Error).message);\n return undefined;\n }\n}\n\n/**\n * Signs and broadcasts a transaction with a mnemonic\n * @param offlineSigner - The offline signer\n * @param messages - The messages to sign and broadcast\n * @param memo - The memo for the transaction\n * @param feegrantGranter - The granter for the transaction\n * @returns The deliver tx response\n */\nexport const signAndBroadcastWithMnemonic = async ({\n offlineSigner,\n messages,\n memo = 'Signing with Mnemonic Demo',\n feegrantGranter,\n network,\n}: {\n offlineSigner: OfflineSigner;\n messages: any[];\n memo?: string;\n feegrantGranter: string;\n network: NETWORK;\n}) => {\n const url = CHAIN_RPC[network];\n if (!url) {\n throw new Error(`Invalid network: ${network}`);\n }\n const signingClient = await createSigningClient(url, offlineSigner);\n const accounts = await offlineSigner.getAccounts();\n const { address } = (accounts[0] ?? {}) as AccountData;\n\n const simGas = await signingClient.simulate(address, messages, memo);\n const gasUsed = simGas > 50000 ? simGas : (messages ?? []).length * 500000;\n const gas = gasUsed * 1.7;\n const gasOptions = calculateTrxGasOptions(gas);\n const fee = {\n amount: [\n {\n denom: 'uixo',\n amount: String(Math.round(gasOptions.average)),\n },\n ],\n gas: String(Math.round(gas)),\n granter: feegrantGranter,\n };\n const result = await signingClient.signAndBroadcast(address, messages, fee, memo, undefined);\n const isDeliverTxFailure = !!result.code;\n if (isDeliverTxFailure) {\n throw new Error(\n `Error when broadcasting tx ${result.transactionHash} at height ${result.height}. Code: ${result.code}; Raw log: ${result.rawLog}`\n );\n }\n};\n\nconst calculateTrxGasOptions = (gasUsed: number) => {\n const gasPriceStep = {\n low: 0.02,\n average: 0.035,\n high: 0.045,\n };\n const gas = gasUsed < 0.01 ? 0.01 : gasUsed;\n const gasOptions = {\n low: gas * gasPriceStep.low,\n average: gas * gasPriceStep.average,\n high: gas * gasPriceStep.high,\n };\n\n return gasOptions;\n};\n\nexport const delay = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));\n\nexport function encrypt(text: string, password: string) {\n const iv = randomBytes(16);\n\n const cipher = createCipheriv('aes-256-cbc', Buffer.from(password.padEnd(32)), iv);\n let encrypted = cipher.update(text);\n encrypted = Buffer.concat([encrypted, cipher.final()]);\n return iv.toString('hex') + ':' + encrypted.toString('hex');\n}\n\nexport type SecpClient = Awaited<ReturnType<typeof getSecpClient>>;\nexport const getSecpClient = async (mnemonic: string) => {\n const wallet = await DirectSecp256k1HdWallet.fromMnemonic(mnemonic, {\n prefix: 'ixo',\n });\n const account = (await wallet.getAccounts())[0];\n\n // Debug: Derive and verify keys manually for comparison\n const seed = await Bip39.mnemonicToSeed(new EnglishMnemonic(mnemonic));\n const hdPath = stringToPath(\"m/44'/118'/0'/0/0\");\n const slip10Result = Slip10.derivePath(Slip10Curve.Secp256k1, seed, hdPath);\n const privkey = slip10Result.privkey;\n // Derive the compressed public key from the private key\n const keypair = await Secp256k1.makeKeypair(privkey);\n const compressedPubkey = Secp256k1.compressPubkey(keypair.pubkey);\n // Log keys and addresses for comparison\n // console.log({\n // walletPubkey: account!.pubkey ? Buffer.from(account!.pubkey).toString('hex') : 'not available',\n // derivedPubkey: Buffer.from(compressedPubkey).toString('hex'),\n // });\n\n const secpClient = {\n mnemonic,\n did: utils.did.generateSecpDid(account!.address),\n baseAccount: account!,\n\n async getAccounts() {\n return (await wallet.getAccounts()) as AccountData[];\n },\n\n async signDirect(signerAddress: any, signDoc: any) {\n return await wallet.signDirect(signerAddress, signDoc);\n },\n\n /**\n * Sign a message with the secp256k1 private key derived from the mnemonic\n * @param message - The message to sign (usually a challenge string - base64 encoded)\n * @returns The signature as a Uint8Array\n */\n async sign(message: string): Promise<Uint8Array> {\n // Use the wallet's signDirect method to ensure consistent signing\n try {\n // Derive keypair from mnemonic directly\n const seed = await Bip39.mnemonicToSeed(new EnglishMnemonic(mnemonic));\n\n // NOTE: need to do checking here if it produces matched address to signed in one, maybe user is using a different derivation path\n // Use the standard Cosmos HD path (m/44'/118'/0'/0/0)\n const hdPath = stringToPath(\"m/44'/118'/0'/0/0\");\n\n // Derive the private key using SLIP-10\n const { privkey } = Slip10.derivePath(Slip10Curve.Secp256k1, seed, hdPath);\n\n // For the challenge (base64 encoded string), decode to get the original bytes\n const challengeBytes = new Uint8Array(Buffer.from(message, 'base64'));\n\n // Hash the challenge bytes using SHA-256\n const messageHash = sha256(challengeBytes);\n\n // Sign the hash with the derived private key\n const signature = await Secp256k1.createSignature(messageHash, privkey);\n\n // Get the fixed-length signature, which is r (32 bytes) | s (32 bytes) | recovery param (1 byte)\n const fixedLengthSignature = signature.toFixedLength();\n\n // Remove the recovery parameter byte (last byte) to get only r and s\n // This gives us exactly 64 bytes which is what the verification expects\n return fixedLengthSignature.slice(0, 64);\n } catch (error) {\n console.error('Error during signature creation:', error);\n throw error;\n }\n },\n };\n\n return secpClient;\n};\n","import { Coin, DecodeObject } from '@cosmjs/proto-signing';\nimport { createRegistry, utils } from '@ixo/impactxclient-sdk';\nimport { Grant } from '@ixo/impactxclient-sdk/types/codegen/cosmos/feegrant/v1beta1/feegrant';\nimport { Timestamp } from '@ixo/impactxclient-sdk/types/codegen/google/protobuf/timestamp';\n\n/**\n * Converts a timestamp object to a timestamp\n * @param timestamp - The timestamp object to convert\n * @returns The timestamp\n */\nexport function convertTimestampObjectToTimestamp(timestamp: Timestamp): number | undefined {\n try {\n const date = utils.proto.fromTimestamp(timestamp);\n\n return date.getTime();\n } catch (error) {\n return undefined;\n }\n}\n\nexport enum FeegrantTypes {\n BASIC_ALLOWANCE = 'BasicAllowance',\n PERIODIC_ALLOWANCE = 'PeriodicAllowance',\n}\n\nexport const FEEGRANT_TYPES: Record<FeegrantTypes, string> = {\n BasicAllowance: '/cosmos.feegrant.v1beta1.BasicAllowance',\n PeriodicAllowance: '/cosmos.feegrant.v1beta1.PeriodicAllowance',\n};\n\n/**\n * Decodes the grant values from the the user's list of allowances\n * @param grants - The grants to decode\n * @returns The decoded grants\n */\nexport const decodeGrants = (grants: Grant[]) => {\n const registry = createRegistry();\n\n return (grants ?? []).map((grant) => {\n const allowance = grant.allowance as DecodeObject;\n const decodedAllowance = registry.decode(allowance);\n // decodedAllowance.\n switch (allowance.typeUrl) {\n case FEEGRANT_TYPES.BasicAllowance:\n return {\n granter: grant.granter,\n grantee: grant.grantee,\n type: FEEGRANT_TYPES.BasicAllowance,\n expiration: decodedAllowance.expiration\n ? convertTimestampObjectToTimestamp(decodedAllowance.expiration)\n : null,\n limit: decodedAllowance.spendLimit?.length\n ? decodedAllowance.spendLimit.find((limit: Coin) => limit.denom === 'uixo')?.amount\n : null,\n msgs: [],\n };\n case FEEGRANT_TYPES.PeriodicAllowance:\n return {\n granter: grant.granter,\n grantee: grant.grantee,\n type: FEEGRANT_TYPES.PeriodicAllowance,\n expiration: decodedAllowance.basic?.expiration\n ? convertTimestampObjectToTimestamp(decodedAllowance.basic.expiration)\n : null,\n limit: decodedAllowance?.periodCanSpend\n ? decodedAllowance?.periodCanSpend?.find((limit: Coin) => limit.denom === 'uixo')?.amount\n : decodedAllowance?.basic?.spendLimit?.length\n ? decodedAllowance?.basic?.spendLimit?.find((limit: Coin) => limit.denom === 'uixo')?.amount\n : null,\n msgs: [],\n };\n default:\n return {\n type: allowance.typeUrl,\n granter: grant.granter,\n grantee: grant.grantee,\n expiration: decodedAllowance.expiration\n ? convertTimestampObjectToTimestamp(decodedAllowance.expiration)\n : decodedAllowance.basic?.expiration\n ? convertTimestampObjectToTimestamp(decodedAllowance.basic.expiration)\n : null,\n limit: decodedAllowance.spendLimit?.length\n ? decodedAllowance.spendLimit.find((limit: Coin) => limit.denom === 'uixo')?.amount\n : decodedAllowance?.periodCanSpend\n ? decodedAllowance?.periodCanSpend?.find((limit: Coin) => limit.denom === 'uixo')?.amount\n : decodedAllowance?.basic?.spendLimit?.length\n ? decodedAllowance?.basic?.spendLimit?.find((limit: Coin) => limit.denom === 'uixo')?.amount\n : null,\n msgs: decodedAllowance.allowedMessages,\n };\n }\n });\n};\n\n/**\n * Checks if the allowance has expired\n * @param expiration - The expiration of the allowance\n * @returns True if the allowance has expired, false otherwise\n */\nexport const isAllowanceExpired = (expiration: number | Timestamp) => {\n if (expiration === null || expiration === undefined) {\n return false;\n }\n const expirationTimestamp =\n typeof expiration === 'object' ? convertTimestampObjectToTimestamp(expiration) : expiration;\n if (expirationTimestamp === undefined || expirationTimestamp === null) {\n // failed to decode or convert - assume expired\n return true;\n }\n return expirationTimestamp < Date.now();\n};\n\n/**\n * Checks if the allowance limit has been reached\n * @param limit - The limit of the allowance\n * @returns True if the allowance limit has been reached, false otherwise\n */\nexport const isAllowanceLimitReached = (limit: number | string | Coin) => {\n if (limit === null || limit === undefined) {\n return false;\n }\n const limitAmount =\n typeof limit === 'object' ? Number(limit?.amount ?? 0) : typeof limit === 'string' ? Number(limit ?? 0) : limit;\n return limitAmount <= 0.0005;\n};\n","import { ixo, utils } from '@ixo/impactxclient-sdk';\nimport { createMatrixApiClient } from '@ixo/matrixclient-sdk';\n\nimport { NETWORK } from '@ixo/signx-sdk/types/types/transact';\nimport { deriveMatrixUrls } from '../common';\nimport {\n checkIsUsernameAvailable,\n createMatrixClient,\n generatePassphraseFromMnemonic,\n generatePasswordFromMnemonic,\n generateUsernameFromAddress,\n generateUserRoomAliasFromAddress,\n hasCrossSigningAccountData,\n mxRegisterWithSecp,\n setupCrossSigning,\n} from './matrix';\nimport { checkIidDocumentExists, createIidDocument, delay, encrypt, getSecpClient } from './utils';\n\nexport interface SimplifiedRegistrationResult {\n address: string;\n did: string;\n mnemonic: string;\n matrixUserId: string;\n matrixRoomId: string;\n matrixMnemonic: string;\n matrixPassword: string;\n matrixAccessToken: string;\n matrixRecoveryPhrase: string;\n matrixHomeServerUrl: string;\n pin: string;\n matrixDeviceName: string;\n}\n\nconst DEVICE_NAME = 'Oracles CLI';\n/**\n * Simplified user registration flow without email verification or passkey authentication\n * Includes: wallet creation, DID creation, Matrix account with secp auth, Matrix room setup, encrypted mnemonic storage\n * @param pin - User PIN for encrypting Matrix mnemonic\n * @param matrixHomeServerUrl - The Matrix homeserver URL to use for registration\n * @returns Registration result with wallet and Matrix account details\n *\n * Note: The returned matrixAccessToken is still valid — the caller is responsible for\n * logging out the oracle's Matrix session after completing any uploads.\n */\nexport async function registerUserSimplified(\n {\n pin,\n oracleName,\n network,\n oracleAvatarUrl,\n matrixHomeServerUrl,\n }: {\n pin: string;\n oracleName: string;\n network: NETWORK;\n oracleAvatarUrl: string;\n matrixHomeServerUrl: string;\n },\n transferTokens: (address: string) => Promise<void>\n): Promise<SimplifiedRegistrationResult> {\n try {\n const { homeServerUrl, roomBotUrl } = deriveMatrixUrls(matrixHomeServerUrl);\n\n // =================================================================================================\n // 1. CREATE WALLET\n // =================================================================================================\n const mnemonic = utils.mnemonic.generateMnemonic();\n const wallet = await getSecpClient(mnemonic);\n const address = wallet.baseAccount.address;\n console.log('✅ Wallet created:', address);\n\n // transfer tokens\n await transferTokens(address);\n\n // =================================================================================================\n // 2. DID CREATION (with {did}#matrix service embedded)\n // =================================================================================================\n const did = utils.did.generateSecpDid(address);\n const didExists = await checkIidDocumentExists(did, network);\n console.log('✅ DID exists:', didExists);\n if (!didExists) {\n console.log('✅ DID does not exist, creating...');\n const matrixService = ixo.iid.v1beta1.Service.fromPartial({\n id: `${did}#matrix`,\n type: 'MatrixHomeServer',\n serviceEndpoint: homeServerUrl,\n });\n await createIidDocument(did, network, wallet, [matrixService]);\n console.log('✅ DID created, waiting 500ms...');\n await delay(500);\n console.log('✅ Checking if DID exists...');\n const didExistsAfterCreation = await checkIidDocumentExists(did, network);\n if (!didExistsAfterCreation) {\n throw new Error('Failed to create DID document');\n }\n }\n console.log('✅ DID created:', did);\n\n // =================================================================================================\n // 3. MATRIX ACCOUNT CREATION\n // =================================================================================================\n const mxMnemonic = utils.mnemonic.generateMnemonic(12);\n const mxUsername = generateUsernameFromAddress(address);\n const mxPassword = generatePasswordFromMnemonic(mxMnemonic);\n const mxPassphrase = generatePassphraseFromMnemonic(mxMnemonic);\n\n // Check if username is available\n const isUsernameAvailable = await checkIsUsernameAvailable({\n homeServerUrl: homeServerUrl,\n username: mxUsername,\n });\n if (!isUsernameAvailable) {\n throw new Error('Matrix account already exists');\n }\n\n // Register using secp256k1 signature (not passkey)\n const account = await mxRegisterWithSecp(address, mxPassword, DEVICE_NAME, wallet, homeServerUrl, roomBotUrl);\n if (!account?.accessToken) {\n throw new Error('Failed to register matrix account');\n }\n console.log('✅ Matrix account created:', account.userId);\n\n // =================================================================================================\n // 4. MATRIX CLIENT SETUP\n // =================================================================================================\n const mxClient = await createMatrixClient({\n homeServerUrl,\n accessToken: account.accessToken,\n userId: account.userId,\n deviceId: account.deviceId,\n });\n\n try {\n await Promise.all([mxClient.setDisplayName(oracleName), mxClient.setAvatarUrl(oracleAvatarUrl)]);\n } catch (error) {\n console.error('Failed to set display name or avatar url:', error);\n }\n\n const matrixApiClient = createMatrixApiClient({\n homeServerUrl: homeServerUrl,\n accessToken: account.accessToken,\n });\n\n // Setup cross signing\n let hasCrossSigning = hasCrossSigningAccountData(mxClient);\n if (!hasCrossSigning) {\n hasCrossSigning = await setupCrossSigning(mxClient, {\n securityPhrase: mxPassphrase,\n password: mxPassword,\n forceReset: true,\n });\n if (!hasCrossSigning) {\n throw new Error('Failed to setup cross signing');\n }\n }\n console.log('✅ Matrix cross-signing setup completed');\n\n // =================================================================================================\n // 5. MATRIX ROOM CREATION/JOIN\n // =================================================================================================\n const mxRoomAlias = generateUserRoomAliasFromAddress(address, account.baseUrl);\n const queryIdResponse = await matrixApiClient.room.v1beta1.queryId(mxRoomAlias).catch(() => undefined);\n let roomId: string = queryIdResponse?.room_id ?? '';\n\n if (!roomId) {\n // Create room via bot\n const response = await fetch(`${roomBotUrl}/room/source`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n did: did,\n userMatrixId: account.userId,\n }),\n });\n if (!response.ok) {\n throw new Error('Failed to create matrix room');\n }\n const data = (await response.json()) as { roomId: string };\n roomId = data.roomId;\n if (!roomId) {\n throw new Error('Failed to create user matrix room');\n }\n }\n\n // Ensure room is joined\n let joinedMembers = await matrixApiClient.room.v1beta1.listJoinedMembers(roomId).catch(() => undefined);\n let joined = !!joinedMembers?.joined?.[account.userId];\n if (!joined) {\n const joinResponse = await matrixApiClient.room.v1beta1.join(roomId);\n if (!joinResponse.room_id) {\n throw new Error('Failed to join matrix room');\n }\n joinedMembers = await matrixApiClient.room.v1beta1.listJoinedMembers(roomId);\n joined = !!joinedMembers?.joined?.[account.userId];\n if (!joined) {\n throw new Error('Failed to join matrix room');\n }\n }\n console.log('✅ Matrix room created/joined:', roomId);\n\n // =================================================================================================\n // 6. ENCRYPT AND STORE MATRIX MNEMONIC\n // =================================================================================================\n const encryptedMnemonic = encrypt(mxMnemonic, pin);\n const storeEncryptedMnemonicResponse = await fetch(\n `${homeServerUrl}/_matrix/client/v3/rooms/${roomId}/state/ixo.room.state.secure/encrypted_mnemonic`,\n {\n method: 'PUT',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${account.accessToken as string}`,\n },\n body: JSON.stringify({\n encrypted_mnemonic: encryptedMnemonic,\n }),\n }\n );\n if (!storeEncryptedMnemonicResponse.ok) {\n throw new Error('Failed to store encrypted mnemonic in matrix room');\n }\n await storeEncryptedMnemonicResponse.json();\n console.log('✅ Encrypted Matrix mnemonic stored in room');\n\n // =================================================================================================\n // 7. STOP MATRIX CLIENT (but do NOT logout — access token is needed for subsequent uploads)\n // The caller is responsible for logging out when done with the oracle's credentials.\n // =================================================================================================\n mxClient.stopClient();\n\n // =================================================================================================\n // 8. RETURN REGISTRATION RESULT\n // =================================================================================================\n return {\n address: address,\n did: did,\n mnemonic: mnemonic, // Wallet mnemonic - store securely!\n matrixUserId: account.userId,\n matrixRoomId: roomId,\n matrixMnemonic: mxMnemonic, // Matrix mnemonic - also store securely!\n matrixPassword: mxPassword,\n matrixAccessToken: account.accessToken,\n matrixRecoveryPhrase: mxPassphrase,\n matrixHomeServerUrl: homeServerUrl,\n pin: pin,\n matrixDeviceName: DEVICE_NAME,\n };\n } catch (error) {\n console.error('Simplified registration failed:', error);\n throw error;\n }\n}\n","import { createMatrixApiClient, utils as mxUtils } from '@ixo/matrixclient-sdk';\nimport { UploadContentType } from '@ixo/matrixclient-sdk/types/api/media/v1beta1';\nimport { createCIDFromBase64, jsonToBase64 } from '../createCIDFromBase64';\n\nexport const publicUpload = async ({\n data,\n fileName,\n homeServerUrl,\n accessToken,\n}: {\n data: object;\n fileName: string;\n homeServerUrl: string;\n accessToken: string;\n}) => {\n const matrixAPIClient = createMatrixApiClient({\n homeServerUrl,\n accessToken,\n });\n\n // Create a simple Buffer instead of using File - this works reliably with node-fetch\n const fileContent = JSON.stringify(data);\n const fileBuffer = Buffer.from(fileContent, 'utf8');\n const fullFileName = fileName + '.json';\n const contentType = 'application/ld+json';\n\n // Pass the buffer directly - node-fetch can handle this reliably in all environments\n const response = await matrixAPIClient.media.v1beta1.upload(\n fullFileName,\n contentType as UploadContentType,\n fileBuffer\n );\n const httpUrl = mxUtils.mxc.mxcUrlToHttp(\n homeServerUrl,\n response.content_uri // the mxc url\n );\n\n if (!httpUrl) {\n throw new Error('Failed to upload file to Matrix');\n }\n\n const jsonString = JSON.stringify(data);\n const base64String = jsonToBase64(jsonString);\n const cid = await createCIDFromBase64(base64String);\n\n return {\n encrypted: 'false',\n cid,\n proof: cid,\n serviceEndpoint: httpUrl,\n mxc: response.content_uri,\n };\n};\n","import { CID } from 'multiformats';\nimport { base64 } from 'multiformats/bases/base64';\nimport * as mfsha2 from 'multiformats/hashes/sha2';\n\nexport async function createCIDFromBase64(base64String: string): Promise<string> {\n // Add 'm' prefix if not present\n const multibaseString = base64String.startsWith('m') ? base64String : 'm' + base64String;\n\n // Decode base64 to bytes\n const bytes = base64.decode(multibaseString);\n\n // Create SHA-256 hash of the bytes\n const hash = await mfsha2.sha256.digest(bytes);\n\n // Create CID (using SHA-256 and RAW codec)\n const cid = CID.create(1, 0x55, hash);\n\n return cid.toString();\n}\n\nexport function jsonToBase64(jsonString: string): string {\n const uint8Array = new TextEncoder().encode(jsonString);\n return btoa(String.fromCharCode(...Array.from(uint8Array)));\n}\n","import * as p from '@clack/prompts';\nimport { NETWORK } from '@ixo/signx-sdk/types/types/transact';\nimport { Command } from '.';\nimport { CLIResult } from '../types';\nimport { registerUserSimplified } from '../utils/account/simplifiedRegistration';\nimport { logoutMatrixClient } from '../utils/account/matrix';\nimport { checkRequiredMatrixUrl, checkRequiredPin, checkRequiredString, MatrixHomeServerUrl, selectNetwork } from '../utils/common';\nimport { RuntimeConfig } from '../utils/runtime-config';\nimport { Wallet } from '../utils/wallet';\n\nexport class CreateUserCommand implements Command {\n name = 'create-user';\n description = 'Create a new user';\n constructor(private wallet: Wallet, private config: RuntimeConfig) {}\n async execute(): Promise<CLIResult> {\n const network = this.config.getValue('network') as NETWORK;\n if (!network) {\n await selectNetwork(this.config);\n }\n\n // Determine default Matrix homeserver URL from wallet or static map\n const defaultMatrixUrl =\n this.wallet.matrixHomeServer ?? MatrixHomeServerUrl[(this.config.getValue('network') as NETWORK) ?? 'devnet'];\n\n const matrixHomeServerUrl = await p.text({\n message: 'Matrix homeserver URL:',\n initialValue: defaultMatrixUrl,\n defaultValue: defaultMatrixUrl,\n validate(value) {\n return checkRequiredMatrixUrl(value);\n },\n });\n if (p.isCancel(matrixHomeServerUrl)) {\n p.log.error('User cancelled');\n process.exit(1);\n }\n\n const pin = await p.text({\n message: 'Enter a 6-digit PIN to secure your Matrix Vault:',\n placeholder: '123456',\n validate(value) {\n return checkRequiredPin(value);\n },\n });\n if (p.isCancel(pin)) {\n p.log.error('User cancelled');\n process.exit(1);\n }\n const oracleName = await p.text({\n message: 'Enter your oracle name',\n initialValue: 'My oracle',\n validate(value) {\n return checkRequiredString(value, 'Oracle name is required');\n },\n });\n if (p.isCancel(oracleName)) {\n p.log.error('User cancelled');\n process.exit(1);\n }\n const user = await registerUserSimplified(\n {\n pin,\n oracleName,\n network: (this.config.getValue('network') as NETWORK) ?? network,\n oracleAvatarUrl: `https://api.dicebear.com/8.x/bottts/svg?seed=${oracleName}`,\n matrixHomeServerUrl,\n },\n async (address) => {\n await this.wallet.sendTokens(address, 150_000); // 150,000 uixo = 0.15 IXO;\n }\n );\n\n // Logout oracle's Matrix session since create-user doesn't need it after\n await logoutMatrixClient({\n baseUrl: user.matrixHomeServerUrl,\n accessToken: user.matrixAccessToken,\n userId: user.matrixUserId,\n deviceId: '',\n });\n\n return { success: true, data: user };\n }\n}\n","import { CLIResult } from '../types';\nimport { Command, CommandRegistry } from './index';\n\nexport class HelpCommand implements Command {\n name = 'help';\n description = 'Show help information and available commands';\n\n constructor(private registry: CommandRegistry) {}\n\n async execute(): Promise<CLIResult> {\n const commands = this.registry.getAll();\n\n const helpText = `\nIXO Oracles CLI - Help\n\nUSAGE:\n oracles-cli [command] [options]\n\nCOMMANDS:\n${commands.map((cmd) => ` ${cmd.name.padEnd(15)} ${cmd.description}`).join('\\n')}\n\nEXAMPLES:\n oracles-cli --init Initialize a new IXO Oracle project\n oracles-cli Launch interactive menu\n oracles-cli help Show this help message\n\nOPTIONS:\n --init Initialize a new project (shortcut)\n --help, -h Show help information\n\nFor more information, visit: https://github.com/ixoworld/ixo-oracles-cli\n`;\n\n return {\n success: true,\n data: helpText,\n };\n }\n}\n","import * as p from '@clack/prompts';\nimport { existsSync } from 'fs';\nimport path from 'path';\nimport simpleGit from 'simple-git';\nimport { Command } from '.';\nimport { CLIResult } from '../types';\nimport { createProjectEnvFile } from '../utils/create-project-env-file';\nimport { RuntimeConfig } from '../utils/runtime-config';\nimport { Wallet } from '../utils/wallet';\nimport { CreateEntityCommand } from './create-entity-command';\n\nexport class InitCommand implements Command {\n name = 'init';\n description = 'Initialize Project';\n\n constructor(private readonly config: RuntimeConfig, private readonly wallet: Wallet) {}\n\n private async getProjectInput(): Promise<{ projectPath: string; projectName: string }> {\n // Get the input from user (could be path, name, or both)\n const input = await p.text({\n message: 'What is your project named?',\n placeholder: 'my-ixo-project',\n validate(value) {\n if (!value) {\n return 'Project name is required';\n }\n return undefined;\n },\n });\n\n if (p.isCancel(input)) {\n p.cancel('Operation cancelled.');\n process.exit(0);\n }\n\n // Parse the input to determine if it's a path, name, or both\n const inputStr = String(input);\n let projectPath: string;\n let projectName: string;\n\n // Check if input contains path separators (is a path)\n if (inputStr.includes('/') || inputStr.includes('\\\\')) {\n // Input is a path\n projectPath = inputStr;\n projectName = path.basename(inputStr);\n } else {\n // Input is just a name, create in current directory\n projectName = inputStr;\n projectPath = path.join(process.cwd(), projectName);\n }\n\n // Ensure the project name is valid\n if (!this.isValidProjectName(projectName)) {\n p.note('Invalid project name. Using a valid name instead.', 'Warning');\n projectName = this.sanitizeProjectName(projectName);\n projectPath = path.join(path.dirname(projectPath), projectName);\n }\n\n return { projectPath, projectName };\n }\n\n private isValidProjectName(name: string): boolean {\n // Check if name is valid (no special characters, starts with letter, etc.)\n const validNameRegex = /^[a-zA-Z][a-zA-Z0-9-_]*$/;\n return validNameRegex.test(name) && name.length > 0 && name.length <= 50;\n }\n\n private sanitizeProjectName(name: string): string {\n // Convert invalid characters to valid ones\n return name\n .replace(/[^a-zA-Z0-9-_]/g, '-')\n .replace(/^-+|-+$/g, '') // Remove leading/trailing dashes\n .toLowerCase()\n .substring(0, 50);\n }\n\n private async confirmProjectCreation(projectPath: string, projectName: string): Promise<boolean> {\n const isDirExists = existsSync(projectPath);\n\n if (isDirExists) {\n const overwrite = await p.confirm({\n message: `Directory \"${projectPath}\" already exists. Do you want to overwrite it?`,\n initialValue: false,\n });\n\n if (p.isCancel(overwrite)) {\n p.cancel('Operation cancelled.');\n process.exit(0);\n }\n\n return overwrite;\n }\n\n // Show confirmation for new project\n const confirm = await p.confirm({\n message: `Create IXO project \"${projectName}\" in \"${projectPath}\"?`,\n initialValue: true,\n });\n\n if (p.isCancel(confirm)) {\n p.cancel('Operation cancelled.');\n process.exit(0);\n }\n\n return confirm;\n }\n\n private async selectRepo() {\n const repo = await p.select({\n message: 'Select a template to clone',\n options: [\n {\n value: 'git@github.com:ixoworld/qiforge.git',\n label: 'IXO Oracles (Default)',\n },\n {\n label: 'Custom template',\n value: 'custom',\n },\n ],\n });\n\n if (p.isCancel(repo)) {\n p.cancel('Operation cancelled.');\n process.exit(0);\n }\n\n if (repo === 'custom') {\n const customRepo = await p.text({\n message: 'Enter the custom template URL',\n });\n\n if (p.isCancel(customRepo)) {\n p.cancel('Operation cancelled.');\n process.exit(0);\n }\n\n return customRepo;\n }\n\n return repo;\n }\n\n private async cloneRepo(repo: string, projectPath: string, shouldOverwrite: boolean = false) {\n const git = simpleGit();\n const cloneSpinner = p.spinner();\n\n try {\n cloneSpinner.start('Cloning repository...');\n\n // If overwriting, remove the existing directory first\n if (shouldOverwrite && existsSync(projectPath)) {\n const { rmSync } = await import('fs');\n rmSync(projectPath, { recursive: true, force: true });\n }\n\n // Create directory if it doesn't exist\n\n await git.clone(repo, projectPath);\n\n // Clean repo and create new git\n const gitFolder = path.join(projectPath, '.git');\n if (existsSync(gitFolder)) {\n const { rmSync } = await import('fs');\n rmSync(gitFolder, { recursive: true, force: true });\n }\n await simpleGit(projectPath).init();\n\n cloneSpinner.stop('Repository cloned successfully');\n\n p.log.info('Creating Oracle Entity and Matrix Account');\n const command = new CreateEntityCommand(this.wallet, this.config);\n const result = await command.execute();\n if (result.success) {\n p.log.info('Oracle Entity and Matrix Account created successfully');\n } else {\n p.log.error('Failed to create Oracle Entity and Matrix Account');\n }\n\n await createProjectEnvFile(this.config);\n // Show success message with next steps\n p.log.success(\n `\\n✅ IXO project created successfully!\\n\\n` +\n `📁 Location: ${projectPath}\\n` +\n `🚀 Next steps:\\n` +\n ` cd ${path.basename(projectPath)}\\n` +\n ` pnpm install\\n` +\n ` pnpm build \\n` +\n ` cd apps/app\\n` +\n ` pnpm start:dev`\n );\n } catch (error) {\n cloneSpinner.stop('Failed to clone repository');\n throw error;\n }\n }\n\n async execute(): Promise<CLIResult> {\n try {\n // Get project input (path and/or name)\n const { projectPath, projectName } = await this.getProjectInput();\n\n // Confirm project creation\n const shouldProceed = await this.confirmProjectCreation(projectPath, projectName);\n\n if (!shouldProceed) {\n return { success: false, data: 'Project creation cancelled' };\n }\n\n // Store in config\n this.config.addValue('projectPath', projectPath);\n this.config.addValue('projectName', projectName);\n\n // Select repository template\n const repo = await this.selectRepo();\n this.config.addValue('repo', repo);\n\n // Check if we need to overwrite\n const shouldOverwrite = existsSync(projectPath);\n\n // Clone the repository\n await this.cloneRepo(repo, projectPath, shouldOverwrite);\n\n return {\n success: true,\n data: `Project \"${projectName}\" created successfully in \"${projectPath}\"`,\n };\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Unknown error occurred',\n };\n }\n }\n}\n","import fs from \"fs\";\nimport path from \"path\";\nimport { NETWORK } from \"@ixo/signx-sdk/types/types/transact\";\nimport { mxLogin } from \"./account/matrix\";\nimport {\n BLOCKSYNC_GRAPHQL_URL,\n CHAIN_RPC,\n DOMAIN_INDEXER_URL,\n MatrixHomeServerUrl,\n MEMORY_ENGINE_API,\n MEMORY_ENGINE_MCP,\n SANDBOX_API,\n SUBSCRIPTION_API,\n} from \"./common\";\nimport { RuntimeConfig } from \"./runtime-config\";\n\ninterface EnvValues {\n oracleName: string;\n network: NETWORK;\n matrixBaseUrl: string;\n matrixAccessToken: string;\n matrixPassword: string;\n matrixUserId: string;\n matrixRecoveryPhrase: string;\n matrixPin: string;\n matrixRoomId: string;\n mnemonic: string;\n entityDid: string;\n oracleAddress: string;\n oracleDid: string;\n}\n\nfunction buildEnvContent(net: NETWORK, values: EnvValues): string {\n return `\nPORT=4000\nORACLE_NAME=${values.oracleName}\n\n# Network\nNETWORK=${net}\nRPC_URL=${CHAIN_RPC[net]}\nBLOCKSYNC_GRAPHQL_URL=${BLOCKSYNC_GRAPHQL_URL[net]}\nBLOCKSYNC_URI=${BLOCKSYNC_GRAPHQL_URL[net]}\n\n# Matrix\nMATRIX_BASE_URL=${values.matrixBaseUrl}\nMATRIX_ORACLE_ADMIN_ACCESS_TOKEN=${values.matrixAccessToken}\nMATRIX_ORACLE_ADMIN_PASSWORD=${values.matrixPassword}\nMATRIX_ORACLE_ADMIN_USER_ID=${values.matrixUserId}\nMATRIX_RECOVERY_PHRASE=\"${values.matrixRecoveryPhrase}\"\nMATRIX_VALUE_PIN=${values.matrixPin}\nMATRIX_ACCOUNT_ROOM_ID=\"${values.matrixRoomId}\"\n\n# Blockchain\nSECP_MNEMONIC=\"${values.mnemonic}\"\nORACLE_ENTITY_DID=${values.entityDid}\n\n# Database\nSQLITE_DATABASE_PATH=./sqlite-db\nREDIS_URL=redis://localhost:6379\n\n# LLM (add your API keys)\nOPENAI_API_KEY=\nOPEN_ROUTER_API_KEY=\n\n# External Services (configure these for your deployment)\nMEMORY_MCP_URL=${MEMORY_ENGINE_MCP[net]}\nMEMORY_ENGINE_URL=${MEMORY_ENGINE_API[net]}\n\n# FIRECRWAL -> check the docs https://docs.firecrawl.dev/mcp-server\nFIRECRAWL_MCP_URL=\nDOMAIN_INDEXER_URL=${DOMAIN_INDEXER_URL[net]}\nSANDBOX_MCP_URL=${SANDBOX_API[net]}\n\n# Observability (optional)\nLANGSMITH_TRACING=true\nLANGSMITH_ENDPOINT=\nLANGSMITH_API_KEY=\nLANGSMITH_PROJECT=\"${values.oracleName}_${net}\"\n\n\nDISABLE_CREDITS=true\nCORS_ORIGIN=*\nSUBSCRIPTION_URL=${SUBSCRIPTION_API[net]}\n\n### BACKUP — save these securely (values above are already set)\n# ORACLE_ADDRESS=${values.oracleAddress}\n# ORACLE_DID=${values.oracleDid}\n`;\n}\n\nfunction buildEnvContentForNetwork(net: NETWORK, oracleName: string): string {\n return `# To fill in the blank values, run: oracles-cli create-entity (select ${net})\n\nPORT=4000\nORACLE_NAME=${oracleName}\n\n# Network\nNETWORK=${net}\nRPC_URL=${CHAIN_RPC[net]}\nBLOCKSYNC_GRAPHQL_URL=${BLOCKSYNC_GRAPHQL_URL[net]}\nBLOCKSYNC_URI=${BLOCKSYNC_GRAPHQL_URL[net]}\n\n# Matrix\nMATRIX_BASE_URL=${MatrixHomeServerUrl[net]}\nMATRIX_ORACLE_ADMIN_ACCESS_TOKEN=\nMATRIX_ORACLE_ADMIN_PASSWORD=\nMATRIX_ORACLE_ADMIN_USER_ID=\nMATRIX_RECOVERY_PHRASE=\nMATRIX_VALUE_PIN=\nMATRIX_ACCOUNT_ROOM_ID=\n\n# Blockchain\nSECP_MNEMONIC=\nORACLE_ENTITY_DID=\n\n# Database\nSQLITE_DATABASE_PATH=./sqlite-db\nREDIS_URL=redis://localhost:6379\n\n# LLM (add your API keys)\nOPENAI_API_KEY=\nOPEN_ROUTER_API_KEY=\n\n# External Services (configure these for your deployment)\nMEMORY_MCP_URL=${MEMORY_ENGINE_MCP[net]}\nMEMORY_ENGINE_URL=${MEMORY_ENGINE_API[net]}\n\n# FIRECRWAL -> check the docs https://docs.firecrawl.dev/mcp-server\nFIRECRAWL_MCP_URL=\nDOMAIN_INDEXER_URL=${DOMAIN_INDEXER_URL[net]}\nSANDBOX_MCP_URL=${SANDBOX_API[net]}\n\n# Observability (optional)\nLANGSMITH_TRACING=true\nLANGSMITH_ENDPOINT=\nLANGSMITH_API_KEY=\nLANGSMITH_PROJECT=\"${oracleName}_${net}\"\n\n\n# Features (optional)\n# DISABLE_CREDITS=false\n# CORS_ORIGIN=*\n# SUBSCRIPTION_URL=${SUBSCRIPTION_API[net]}\n`;\n}\n\nfunction writeEnvFile(filePath: string, content: string): void {\n try {\n fs.writeFileSync(filePath, content);\n console.log(\"✅ env file created successfully at:\", filePath);\n } catch (error) {\n console.error(\"❌ Failed to create env file:\", filePath, error);\n throw error;\n }\n}\n\nexport const createProjectEnvFile = async (config: RuntimeConfig) => {\n const oracleMatrixHomeServerUrl = config.getOrThrow(\n \"oracleMatrixHomeServerUrl\",\n );\n const network = config.getOrThrow(\"network\") as NETWORK;\n const regResult = config.getOrThrow(\"registerUserResult\");\n\n const freshMx = await mxLogin({\n homeServerUrl: oracleMatrixHomeServerUrl,\n username: regResult.matrixUserId,\n password: regResult.matrixPassword,\n deviceName: regResult.matrixDeviceName,\n });\n const projectPath = config.getOrThrow(\"projectPath\");\n const envDir = path.join(projectPath, \"apps\", \"app\");\n\n console.log(\"Creating env files in:\", envDir);\n\n if (!fs.existsSync(envDir)) {\n console.log(\"Creating directory:\", envDir);\n fs.mkdirSync(envDir, { recursive: true });\n }\n\n const oracleName = (config.getValue(\"projectName\") as string) ?? \"\";\n\n // Write main .env with full values for the current network\n const envContent = buildEnvContent(network, {\n oracleName,\n network,\n matrixBaseUrl: oracleMatrixHomeServerUrl,\n matrixAccessToken: freshMx.accessToken,\n matrixPassword: regResult.matrixPassword,\n matrixUserId: regResult.matrixUserId,\n matrixRecoveryPhrase: regResult.matrixRecoveryPhrase,\n matrixPin: regResult.pin,\n matrixRoomId: regResult.matrixRoomId,\n mnemonic: regResult.mnemonic,\n entityDid: config.getOrThrow(\"entityDid\"),\n oracleAddress: regResult.address,\n oracleDid: regResult.did,\n });\n // Write full values to network-specific file (e.g. .env.testnet)\n const networkFilename = `.env.${network}`;\n writeEnvFile(path.join(envDir, networkFilename), envContent);\n\n // Copy to .env (active config the app reads)\n writeEnvFile(path.join(envDir, \".env\"), envContent);\n\n // Write blank templates for other networks only if they don't already exist\n const allNetworks: { net: NETWORK; filename: string }[] = [\n { net: \"devnet\", filename: \".env.devnet\" },\n { net: \"testnet\", filename: \".env.testnet\" },\n { net: \"mainnet\", filename: \".env.mainnet\" },\n ];\n\n for (const { net, filename } of allNetworks) {\n if (net === network) continue;\n const filePath = path.join(envDir, filename);\n if (fs.existsSync(filePath)) continue;\n const content = buildEnvContentForNetwork(net, oracleName);\n writeEnvFile(filePath, content);\n }\n};\n","import { confirm } from '@clack/prompts';\nimport { CLIResult } from '../types';\nimport { Wallet } from '../utils/wallet';\nimport { Command } from './index';\n\nexport class LogoutCommand implements Command {\n name = 'logout';\n description = 'Logout command';\n\n constructor(private wallet: Wallet) {}\n\n async execute(): Promise<CLIResult> {\n const shouldClear = await confirm({\n message: 'Are you sure you want to logout?',\n initialValue: false,\n });\n if (shouldClear) {\n await this.wallet.clearWallet();\n return {\n success: true,\n data: 'Logged out successfully',\n };\n }\n return {\n success: false,\n error: 'Logout cancelled',\n };\n }\n}\n","import { toHex } from '@cosmjs/encoding';\nimport { EncodeObject } from '@cosmjs/proto-signing';\nimport { createRegistry } from '@ixo/impactxclient-sdk';\nimport {\n SignX as IxoSignX,\n SIGN_X_LOGIN_ERROR,\n SIGN_X_LOGIN_SUCCESS,\n SIGN_X_TRANSACT_ERROR,\n SIGN_X_TRANSACT_SUCCESS,\n} from '@ixo/signx-sdk';\nimport { LOGIN_DATA } from '@ixo/signx-sdk/types/types/transact';\nimport qrcode from 'qrcode-terminal';\nimport { WalletProps } from './types';\n\nconst SignXEndpoints = {\n devnet: 'https://signx.devnet.ixo.earth',\n testnet: 'https://signx.testnet.ixo.earth',\n mainnet: 'https://signx.ixo.earth',\n};\n\nexport class SignXClient {\n private readonly signXClient: IxoSignX;\n private _loginData?: LOGIN_DATA;\n public get loginData() {\n return this._loginData;\n }\n\n static loadFromWallet(wallet: WalletProps) {\n return new IxoSignX({\n endpoint: SignXEndpoints[wallet.network],\n sitename: 'IXO Oracles CLI',\n network: wallet.network,\n });\n }\n\n constructor(chainNetwork: keyof typeof SignXEndpoints) {\n this.signXClient = new IxoSignX({\n endpoint: SignXEndpoints[chainNetwork],\n sitename: 'IXO Oracles CLI',\n network: chainNetwork,\n });\n }\n\n async login() {\n const loginData = await this.signXClient.login({ pollingInterval: 2000, matrix: true });\n this._loginData = loginData;\n return loginData;\n }\n\n private displayStyledQRCode(qrCodeData: string | LOGIN_DATA, title: string) {\n const qrCodeStr = typeof qrCodeData === 'string' ? qrCodeData : JSON.stringify(qrCodeData);\n\n // Display title with emoji\n console.log('\\n' + ' '.repeat(5) + '🔐 ' + title);\n console.log(' '.repeat(5) + '📱 Scan with IXO app');\n console.log(' '.repeat(5) + '━'.repeat(30));\n\n // Generate very compact QR code\n qrcode.generate(qrCodeStr, {\n small: true,\n });\n console.log(' '.repeat(5) + '⏳ Waiting...\\n');\n }\n\n public displayQRCode(qrCodeData: string | LOGIN_DATA) {\n this.displayStyledQRCode(qrCodeData, 'Login with SignX');\n }\n\n async awaitLogin() {\n return new Promise<WalletProps>((resolve, reject) => {\n try {\n this.signXClient.on(SIGN_X_LOGIN_SUCCESS, (response: { data: WalletProps }) => {\n if (!response.data) {\n reject(new Error('Login failed'));\n return;\n }\n if (!response.data.matrix) {\n reject(new Error('Matrix login failed'));\n return;\n }\n resolve(response.data); // Resolve the promise with the login success data\n });\n\n this.signXClient.on(SIGN_X_LOGIN_ERROR, (error) => {\n console.log('Login error:', error);\n reject(error); // Reject the promise with the login error\n });\n\n // Use loginRequest data to show QR code to user for scanning by mobile app\n } catch (error) {\n console.error('Error in connecting:', error);\n reject(error); // Reject the promise with any other errors\n }\n });\n }\n\n async transact(messages: readonly EncodeObject[], wallet: WalletProps, memo?: string) {\n const registry = createRegistry();\n\n return this.signXClient.transact({\n address: wallet.address,\n did: wallet.did,\n pubkey: wallet.pubKey,\n timestamp: new Date().toISOString(),\n transactions: [\n {\n sequence: 1,\n txBodyHex: toHex(registry.encodeTxBody({ messages: messages, memo: memo || '' })),\n },\n ],\n });\n }\n\n async awaitTransaction() {\n return new Promise((resolve, reject) => {\n try {\n this.signXClient.on(SIGN_X_TRANSACT_SUCCESS, (result) => {\n resolve(result.data); // Resolve the promise with the login success data\n });\n\n this.signXClient.on(SIGN_X_TRANSACT_ERROR, (error) => {\n reject(error); // Reject the promise with the login error\n });\n // Use loginRequest data to show QR code to user for scanning by mobile app\n } catch (error) {\n console.error('Error in connecting:', error);\n reject(error); // Reject the promise with any other errors\n }\n });\n }\n\n async pollNextTransaction() {\n return this.signXClient.pollNextTransaction();\n }\n\n displayTransactionQRCode(qrCodeData: string) {\n this.displayStyledQRCode(qrCodeData, 'SIGNX TRANSACTION');\n }\n}\n","import { CLIResult } from '../types';\nimport { selectNetwork } from '../utils/common';\nimport { RuntimeConfig } from '../utils/runtime-config';\nimport { SignXClient } from '../utils/signx/signx';\nimport { Wallet } from '../utils/wallet';\nimport { Command } from './index';\n\nexport class SignXLoginCommand implements Command {\n name = 'signx-login';\n description = 'Login with SignX wallet';\n\n constructor(private wallet: Wallet, private config: RuntimeConfig) {}\n\n async execute(): Promise<CLIResult> {\n try {\n // Select network and create SignX client\n const network = await selectNetwork(this.config);\n const signXClient = new SignXClient(network);\n\n // Start login process\n const loginData = await signXClient.login();\n\n // Display QR code for user to scan\n signXClient.displayQRCode(loginData);\n\n // Wait for login completion\n const loginResult = await signXClient.awaitLogin();\n this.wallet.setWallet(loginResult);\n this.wallet.setSignXClient(signXClient);\n return {\n success: true,\n data: {\n message: 'Successfully logged in with SignX!',\n wallet: {\n address: loginResult.address,\n did: loginResult.did,\n name: loginResult.name,\n },\n },\n };\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? `SignX login failed: ${error.message}` : 'Unknown error',\n };\n }\n }\n}\n","import * as p from '@clack/prompts';\nimport { NETWORK } from '@ixo/signx-sdk/types/types/transact';\nimport { Command } from '.';\nimport { CLIResult } from '../types';\nimport { checkIsEntityDid, checkRequiredURL, selectNetwork } from '../utils/common';\nimport { CreateEntity } from '../utils/entity';\nimport { RuntimeConfig } from '../utils/runtime-config';\nimport { Wallet } from '../utils/wallet';\n\nexport class UpdateDomainCommand implements Command {\n name = 'update-oracle-api-url';\n description = 'Update the oracle API domain (default is localhost)';\n\n constructor(private wallet: Wallet, private config: RuntimeConfig) {}\n\n async execute(): Promise<CLIResult> {\n const network = this.config.getValue('network') as NETWORK;\n if (!network) {\n await selectNetwork(this.config);\n }\n\n const results = await p.group(\n {\n entityDid: () =>\n p.text({\n message: 'What is the DID of the entity you want to update?',\n initialValue: this.config.getValue('entityDid')?.toString() ?? '',\n validate(value) {\n return checkIsEntityDid(value);\n },\n }),\n apiUrl: () =>\n p.text({\n message: 'What is the new API URL (domain) for the oracle?',\n initialValue: 'http://localhost:4000',\n validate(value) {\n return checkRequiredURL(value, 'API URL is required and must be a valid URL');\n },\n }),\n },\n {\n onCancel: () => {\n p.cancel('Operation cancelled.');\n process.exit(0);\n },\n }\n );\n\n try {\n const createEntity = new CreateEntity(this.wallet, this.config);\n p.log.info(`Updating oracle domain for entity ${results.entityDid} to ${results.apiUrl}`);\n await createEntity.updateOracleDomain(results.entityDid, results.apiUrl);\n return {\n success: true,\n data: `Oracle domain updated to ${results.apiUrl} for entity ${results.entityDid}`,\n };\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : String(error),\n };\n }\n }\n}\n","import * as p from '@clack/prompts';\nimport { NETWORK } from '@ixo/signx-sdk/types/types/transact';\nimport { Command } from '.';\nimport { CLIResult } from '../types';\nimport { checkIsEntityDid, selectNetwork } from '../utils/common';\nimport { CreateEntity } from '../utils/entity';\nimport { RuntimeConfig } from '../utils/runtime-config';\nimport { Wallet } from '../utils/wallet';\n\nexport class UpdateEntityCommand implements Command {\n name = 'update-entity';\n description = 'Update an entity (add controllers, etc.)';\n private readonly createEntity: CreateEntity;\n\n constructor(private wallet: Wallet, private config: RuntimeConfig) {\n this.createEntity = new CreateEntity(this.wallet, this.config);\n }\n\n async execute(): Promise<CLIResult> {\n const network = this.config.getValue('network') as NETWORK;\n if (!network) {\n await selectNetwork(this.config);\n }\n\n const results = await p.group(\n {\n entityDid: () =>\n p.text({\n message: 'What is the DID of the entity you want to update?',\n initialValue: this.config.getValue('entityDid')?.toString() ?? '',\n validate(value) {\n return checkIsEntityDid(value);\n },\n }),\n action: () =>\n p.select({\n message: 'What would you like to do?',\n options: [\n {\n value: 'add-controller',\n label: 'Add Controller',\n hint: 'Add a new controller DID to the entity',\n },\n ],\n initialValue: 'add-controller',\n }),\n controllerDid: async ({ results }): Promise<string> => {\n if (results.action !== 'add-controller') {\n throw new Error('Unknown action');\n }\n const did = await p.text({\n message: 'What is the DID of the controller you want to add?',\n validate(value) {\n return checkIsEntityDid(value);\n },\n });\n if (p.isCancel(did)) {\n p.cancel('Operation cancelled.');\n process.exit(0);\n }\n return did;\n },\n },\n {\n onCancel: () => {\n p.cancel('Operation cancelled.');\n process.exit(0);\n },\n }\n );\n\n try {\n if (results.action === 'add-controller' && typeof results.controllerDid === 'string') {\n const controllerDid = results.controllerDid;\n const entityDid = results.entityDid;\n p.log.info(`Adding controller ${controllerDid} to entity ${entityDid}`);\n await this.createEntity.addControllerToEntity(entityDid, controllerDid);\n p.log.success(`Controller ${controllerDid} successfully added to entity ${entityDid}`);\n return {\n success: true,\n data: `Controller ${controllerDid} added to entity ${entityDid}`,\n };\n }\n\n return {\n success: false,\n error: 'Unknown action',\n };\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : String(error),\n };\n }\n }\n}\n","export class CLIError extends Error {\n constructor(message: string, public code: string = 'CLI_ERROR', public suggestions?: string[]) {\n super(message);\n this.name = 'CLIError';\n }\n}\n\nexport class ConfigError extends CLIError {\n constructor(message: string, suggestions?: string[]) {\n super(message, 'CONFIG_ERROR', suggestions);\n this.name = 'ConfigError';\n }\n}\n\nexport class NetworkError extends CLIError {\n constructor(message: string, suggestions?: string[]) {\n super(message, 'NETWORK_ERROR', suggestions);\n this.name = 'NetworkError';\n }\n}\n\nexport class ValidationError extends CLIError {\n constructor(message: string, suggestions?: string[]) {\n super(message, 'VALIDATION_ERROR', suggestions);\n this.name = 'ValidationError';\n }\n}\n\nexport function handleError(error: unknown): never {\n if (error instanceof CLIError) {\n console.error(`\\n❌ ${error.name}: ${error.message}`);\n if (error.suggestions?.length) {\n console.error('\\nSuggestions:');\n error.suggestions.forEach((suggestion) => console.error(` • ${suggestion}`));\n }\n process.exit(1);\n }\n\n if (error instanceof Error) {\n console.error(`\\n❌ Unexpected Error: ${error.message}`);\n if (error.stack) {\n console.error('\\nStack trace:');\n console.error(error.stack);\n }\n process.exit(1);\n }\n\n console.error('\\n❌ Unknown error occurred' , error);\n process.exit(1);\n}\n","import { NETWORK } from '@ixo/signx-sdk/types/types/transact';\nimport { SimplifiedRegistrationResult } from './account/simplifiedRegistration';\n\ninterface Config {\n authZFile: string;\n feesFile: string;\n projectPath: string;\n projectName: string;\n entityDid: string;\n network: NETWORK;\n repo: string;\n oracleMatrixHomeServerUrl: string;\n registerUserResult: SimplifiedRegistrationResult & {\n matrixDeviceName: string;\n };\n}\n\nexport class RuntimeConfig {\n private config: Partial<Config> = {};\n private static instance: RuntimeConfig;\n private constructor() {}\n\n public static getInstance(): RuntimeConfig {\n if (!RuntimeConfig.instance) {\n RuntimeConfig.instance = new RuntimeConfig();\n }\n return RuntimeConfig.instance;\n }\n\n public addValue<K extends keyof Config>(key: K, value: Config[K]) {\n this.config[key] = value;\n }\n\n public getValue(key: keyof Config) {\n return this.config[key];\n }\n\n public getOrThrow<K extends keyof Config>(key: K): Config[K] {\n const value = this.getValue(key);\n if (!value) {\n throw new Error(`Value ${key} is not set`);\n }\n return value as Config[K];\n }\n\n public getConfig() {\n return this.config;\n }\n\n public deleteValue(key: keyof Config) {\n delete this.config[key];\n }\n}\n","import { log } from '@clack/prompts';\nimport { cosmos } from '@ixo/impactxclient-sdk';\nimport { existsSync, readFileSync, writeFileSync } from 'fs';\nimport { unlink } from 'fs/promises';\nimport os from 'os';\nimport path from 'path';\nimport { RuntimeConfig } from './runtime-config';\nimport { SignXClient } from './signx/signx';\nimport { WalletProps } from './signx/types';\n\n// Use hidden .wallet.json file in user's home directory\nconst WALLET_PATH = path.join(os.homedir(), '.wallet.json');\n\n// for dev make it here\n// const WALLET_PATH = path.join(__dirname, '.wallet.json');\n\nexport class Wallet {\n public wallet: WalletProps | undefined;\n public signXClient?: SignXClient;\n private config: RuntimeConfig;\n constructor(config: RuntimeConfig) {\n this.config = config;\n this.loadWallet();\n }\n\n public setSignXClient(signXClient: SignXClient) {\n this.signXClient = signXClient;\n }\n\n private loadWallet() {\n if (existsSync(WALLET_PATH)) {\n try {\n const walletData = readFileSync(WALLET_PATH, 'utf8');\n this.wallet = JSON.parse(walletData) as WalletProps;\n\n // Validate that matrix userId is present — required for homeserver derivation\n if (!this.wallet.matrix?.userId || !this.wallet.matrix.userId.includes(':')) {\n log.warning('Wallet is missing valid Matrix credentials. Please re-authenticate via SignX.');\n this.wallet = undefined;\n return;\n }\n\n // Use wallet.network directly from WalletProps (provided by SignX)\n let network = this.wallet.network;\n\n // Fallback: derive network from matrix domain for wallets saved before network field was added\n if (!network) {\n const mxDomain = this.wallet.matrix.userId.split(':')[1];\n const mxDomainToNetwork = {\n 'devmx.ixo.earth': 'devnet',\n 'testmx.ixo.earth': 'testnet',\n 'mx.ixo.earth': 'mainnet',\n } as const;\n network = mxDomainToNetwork[mxDomain as keyof typeof mxDomainToNetwork];\n if (!network) {\n throw new Error(`Cannot determine network from matrix domain: ${mxDomain}`);\n }\n this.wallet.network = network;\n }\n\n this.config.addValue('network', network);\n\n // set signx client\n this.setSignXClient(new SignXClient(network));\n log.success(`Welcome back, ${this.wallet.name}!`);\n log.info(`Network: ${network}`);\n } catch (error) {\n log.warning(`Failed to load wallet file: ${error instanceof Error ? error.message : String(error)}`);\n this.wallet = undefined;\n }\n } else {\n log.warning('No wallet file found');\n }\n }\n\n setWallet(wallet: WalletProps) {\n try {\n this.wallet = wallet;\n\n const walletJson = JSON.stringify(wallet, null, 2);\n writeFileSync(WALLET_PATH, walletJson, 'utf8');\n log.success(`Wallet saved successfully to: ${WALLET_PATH}`);\n } catch (error) {\n log.error(`Failed to save wallet: ${error instanceof Error ? error.message : String(error)}`);\n throw new Error('Failed to save wallet file');\n }\n }\n\n public checkWalletExists() {\n return existsSync(WALLET_PATH) && this.wallet !== undefined;\n }\n\n public async clearWallet() {\n this.wallet = undefined;\n try {\n if (existsSync(WALLET_PATH)) {\n await unlink(WALLET_PATH);\n log.success('Wallet file deleted successfully');\n }\n } catch (error) {\n log.error(`Failed to delete wallet file: ${error instanceof Error ? error.message : String(error)}`);\n }\n }\n\n get did() {\n return this.wallet?.did;\n }\n\n get address() {\n return this.wallet?.address;\n }\n\n get name() {\n return this.wallet?.name;\n }\n\n get pubKey() {\n return this.wallet?.pubKey;\n }\n\n get algo() {\n return this.wallet?.algo;\n }\n\n get matrix() {\n return this.wallet?.matrix;\n }\n\n /**\n * Extracts the Matrix homeserver URL from the user's matrix userId.\n * e.g. @user:devmx.ixo.earth → https://devmx.ixo.earth\n */\n get matrixHomeServer(): string | undefined {\n const userId = this.wallet?.matrix?.userId;\n if (!userId || !userId.includes(':')) return undefined;\n const domain = userId.split(':')[1];\n return `https://${domain}`;\n }\n\n public reloadWallet() {\n this.loadWallet();\n }\n\n async sendTokens(address: string, amount: number) {\n if (!this.address || !this.signXClient || !this.wallet) {\n throw new Error('Wallet not loaded');\n }\n const sendTokensToUserMsg = {\n typeUrl: '/cosmos.bank.v1beta1.MsgSend',\n value: cosmos.bank.v1beta1.MsgSend.fromPartial({\n fromAddress: this.address,\n toAddress: address,\n amount: [\n cosmos.base.v1beta1.Coin.fromPartial({\n amount: amount.toString(),\n denom: 'uixo',\n }),\n ],\n }),\n };\n const tx = await this.signXClient?.transact([sendTokensToUserMsg], this.wallet);\n this.signXClient?.displayTransactionQRCode(JSON.stringify(tx));\n await this.signXClient?.pollNextTransaction();\n const response = await this.signXClient?.awaitTransaction();\n return response;\n }\n}\n"],"mappings":"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","names":["cancel","intro","isCancel","log","outro","select","spinner","process","CommandRegistry","command","name","cmd","p","select","z","selectNetwork","config","network","RELAYER_NODE_DID","MatrixHomeServerUrl","PORTAL_URL","CHAIN_RPC","DOMAIN_INDEXER_URL","BLOCKSYNC_GRAPHQL_URL","MEMORY_ENGINE_API","MEMORY_ENGINE_MCP","SANDBOX_API","SUBSCRIPTION_API","checkRequiredString","value","message","result","z","checkIsEntityDid","checkRequiredURL","checkRequiredNumber","checkRequiredPin","v","checkRequiredMatrixUrl","deriveMatrixUrls","homeServerUrl","url","domain","protocol","isCancel","log","spinner","text","customMessages","ixo","utils","sha256","eciesEncrypt","ClientEvent","createClient","md5","secretStorageKeys","hasPrivateKey","keyId","secretStorageKeys","getPrivateKey","clearSecretStorageKeys","secretStorageKeys","getSecretStorageKey","keys","keyIds","keyId","hasPrivateKey","privateKey","getPrivateKey","cacheSecretStorageKey","keyInfo","Bip39","EnglishMnemonic","Secp256k1","sha256","Slip10","Slip10Curve","stringToPath","DirectSecp256k1HdWallet","createQueryClient","createSigningClient","customMessages","ixo","utils","createCipheriv","randomBytes","createRegistry","utils","convertTimestampObjectToTimestamp","timestamp","FEEGRANT_TYPES","decodeGrants","grants","registry","createRegistry","grant","allowance","decodedAllowance","convertTimestampObjectToTimestamp","limit","isAllowanceExpired","expiration","expirationTimestamp","isAllowanceLimitReached","checkIidDocumentExists","did","network","url","CHAIN_RPC","createQueryClient","error","createIidDocument","offlineSigner","services","accounts","address","pubkey","allowances","queryAddressAllowances","feegrantGranter","decodeGrants","allowance","isAllowanceExpired","isAllowanceLimitReached","trx","ixo","customMessages","signAndBroadcastWithMnemonic","messages","memo","signingClient","createSigningClient","simGas","gas","gasOptions","calculateTrxGasOptions","fee","result","gasUsed","gasPriceStep","delay","ms","resolve","encrypt","text","password","iv","randomBytes","cipher","createCipheriv","encrypted","getSecpClient","mnemonic","wallet","DirectSecp256k1HdWallet","account","seed","Bip39","EnglishMnemonic","hdPath","stringToPath","privkey","Slip10","Slip10Curve","keypair","Secp256k1","compressedPubkey","utils","signerAddress","signDoc","message","challengeBytes","messageHash","sha256","WELL_KNOWN_URI","mxLogin","homeServerUrl","username","password","deviceName","localMatrix","mxHomeServerUrl","mxUsername","mxIdMatch","getBaseUrl","client","createTemporaryClient","response","normalizeUsername","error","msg","getPublicKeyForEncryption","roomBotUrl","createUserCreationChallenge","address","challenge","challengeBase64","encryptPasswordWithECIES","publicKey","publicKeyBytes","passwordBytes","encryptedPassword","eciesEncrypt","byte","createUserAccountWithSecp","signature","publicKeyInfo","request","responseText","errorMessage","errorData","mxRegisterWithSecp","wallet","signatureBytes","generateUsernameFromAddress","checkIsUsernameAvailable","createClient","createMatrixClient","accessToken","userId","deviceId","mxClient","getSecretStorageKey","cacheSecretStorageKey","resolve","reject","sync","ClientEvent","state","logoutMatrixClient","baseUrl","hasCrossSigningAccountData","masterKeyData","setupCrossSigning","securityPhrase","forceReset","skipBootstrapSecureStorage","clearSecretStorageKeys","mxCrypto","recoveryKey","makeRequest","getAuthId","delay","generatePasswordFromMnemonic","mnemonic","md5","generatePassphraseFromMnemonic","mnemonic","hash","sha256","cleanMatrixHomeServerUrl","homeServer","generateUserRoomNameFromAddress","address","postpend","generateUserRoomAliasFromAddress","homeServerUrl","getBaseUrl","servername","protocol","serverDiscoveryUrl","WELL_KNOWN_URI","baseUrl","normalizeUsername","rawUsername","getAuthId","userId","password","ixo","utils","createMatrixApiClient","DEVICE_NAME","registerUserSimplified","pin","oracleName","network","oracleAvatarUrl","matrixHomeServerUrl","transferTokens","homeServerUrl","roomBotUrl","deriveMatrixUrls","mnemonic","utils","wallet","getSecpClient","address","did","didExists","checkIidDocumentExists","matrixService","ixo","createIidDocument","delay","mxMnemonic","mxUsername","generateUsernameFromAddress","mxPassword","generatePasswordFromMnemonic","mxPassphrase","generatePassphraseFromMnemonic","checkIsUsernameAvailable","account","mxRegisterWithSecp","mxClient","createMatrixClient","error","matrixApiClient","createMatrixApiClient","hasCrossSigning","hasCrossSigningAccountData","setupCrossSigning","mxRoomAlias","generateUserRoomAliasFromAddress","roomId","response","joinedMembers","joined","encryptedMnemonic","encrypt","storeEncryptedMnemonicResponse","createMatrixApiClient","mxUtils","CID","base64","mfsha2","createCIDFromBase64","base64String","multibaseString","bytes","hash","jsonToBase64","jsonString","uint8Array","publicUpload","data","fileName","homeServerUrl","accessToken","matrixAPIClient","createMatrixApiClient","fileContent","fileBuffer","fullFileName","response","httpUrl","mxUtils","jsonString","base64String","jsonToBase64","cid","createCIDFromBase64","CreateEntity","wallet","config","matrixHomeServerUrl","ixo","customMessages","RELAYER_NODE_DID","utils","msg","oracleAccountAddress","linkedAccounts","account","oracleName","entityDid","homeServerUrl","accessToken","response","publicUpload","price","denom","newApiUrl","walletAddress","deleteApiMsg","deleteWsMsg","addApiMsg","addWsMsg","log","tx","controllerDid","addControllerMsg","linkedResourcesMsgs","resource","profile","validFrom","domainCard","orgName","name","logo","coverImage","location","description","services","service","parentProtocol","network","indexerUrl","DOMAIN_INDEXER_URL","errorText","error","params","pin","text","value","checkRequiredPin","isCancel","registerResult","registerUserSimplified","address","oracleHomeServerUrl","oracleAccessToken","profileResource","did","domainCardResource","addDomainCardMsg","domainCardTx","logoutMatrixClient","s","spinner","key","CreateEntityCommand","wallet","config","selectNetwork","defaultMatrixUrl","MatrixHomeServerUrl","results","value","checkRequiredMatrixUrl","checkRequiredString","checkRequiredNumber","checkRequiredURL","did","CreateEntity","portalUrl","PORTAL_URL","p","CreateUserCommand","wallet","config","network","selectNetwork","defaultMatrixUrl","MatrixHomeServerUrl","matrixHomeServerUrl","value","checkRequiredMatrixUrl","pin","checkRequiredPin","oracleName","checkRequiredString","user","registerUserSimplified","address","logoutMatrixClient","HelpCommand","registry","cmd","p","existsSync","path","simpleGit","fs","path","buildEnvContent","net","values","CHAIN_RPC","BLOCKSYNC_GRAPHQL_URL","MEMORY_ENGINE_MCP","MEMORY_ENGINE_API","DOMAIN_INDEXER_URL","SANDBOX_API","SUBSCRIPTION_API","buildEnvContentForNetwork","oracleName","MatrixHomeServerUrl","writeEnvFile","filePath","content","fs","error","createProjectEnvFile","config","oracleMatrixHomeServerUrl","network","regResult","freshMx","mxLogin","projectPath","envDir","path","envContent","networkFilename","allNetworks","filename","InitCommand","config","wallet","input","value","inputStr","projectPath","projectName","path","name","existsSync","overwrite","confirm","repo","customRepo","shouldOverwrite","git","simpleGit","cloneSpinner","rmSync","gitFolder","CreateEntityCommand","createProjectEnvFile","error","confirm","LogoutCommand","wallet","toHex","createRegistry","IxoSignX","SIGN_X_LOGIN_ERROR","SIGN_X_LOGIN_SUCCESS","SIGN_X_TRANSACT_ERROR","SIGN_X_TRANSACT_SUCCESS","qrcode","SignXEndpoints","SignXClient","wallet","chainNetwork","loginData","qrCodeData","title","qrCodeStr","resolve","reject","response","error","messages","memo","registry","result","SignXLoginCommand","wallet","config","network","selectNetwork","signXClient","SignXClient","loginData","loginResult","error","p","UpdateDomainCommand","wallet","config","selectNetwork","results","value","checkIsEntityDid","checkRequiredURL","createEntity","CreateEntity","error","p","UpdateEntityCommand","wallet","config","CreateEntity","selectNetwork","results","value","checkIsEntityDid","did","controllerDid","entityDid","error","CLIError","message","code","suggestions","handleError","error","CLIError","suggestion","RuntimeConfig","_RuntimeConfig","key","value","log","cosmos","existsSync","readFileSync","writeFileSync","unlink","os","path","WALLET_PATH","path","os","Wallet","config","signXClient","existsSync","walletData","readFileSync","log","network","mxDomain","SignXClient","error","wallet","walletJson","writeFileSync","unlink","userId","address","amount","sendTokensToUserMsg","cosmos","tx","CLIManager","CommandRegistry","RuntimeConfig","Wallet","InitCommand","CreateEntityCommand","UpdateEntityCommand","UpdateDomainCommand","CreateUserCommand","LogoutCommand","HelpCommand","result","login","select","isCancel","cancel","process","SignXLoginCommand","log","commandName","command","s","spinner","intro","action","args","userArgs","error","handleError","outro","cli"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "qiforge-cli",
|
|
3
|
+
"version": "1.1.0",
|
|
4
|
+
"description": "CLI tool for creating and managing IXO Oracle projects",
|
|
5
|
+
"main": "dist/cli.js",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"bin": {
|
|
8
|
+
"oracles-cli": "./dist/cli.js"
|
|
9
|
+
},
|
|
10
|
+
"preferGlobal": true,
|
|
11
|
+
"keywords": [
|
|
12
|
+
"cli",
|
|
13
|
+
"ixo",
|
|
14
|
+
"blockchain",
|
|
15
|
+
"oracles",
|
|
16
|
+
"ai",
|
|
17
|
+
"matrix",
|
|
18
|
+
"signx"
|
|
19
|
+
],
|
|
20
|
+
"author": "IXO Foundation",
|
|
21
|
+
"license": "ISC",
|
|
22
|
+
"repository": {
|
|
23
|
+
"type": "git",
|
|
24
|
+
"url": "https://github.com/ixoworld/ixo-oracles-cli.git"
|
|
25
|
+
},
|
|
26
|
+
"bugs": {
|
|
27
|
+
"url": "https://github.com/ixoworld/ixo-oracles-cli/issues"
|
|
28
|
+
},
|
|
29
|
+
"homepage": "https://github.com/ixoworld/ixo-oracles-cli#readme",
|
|
30
|
+
"engines": {
|
|
31
|
+
"node": ">=22.0.0",
|
|
32
|
+
"pnpm": ">=10.0.0"
|
|
33
|
+
},
|
|
34
|
+
"files": [
|
|
35
|
+
"dist",
|
|
36
|
+
"README.md"
|
|
37
|
+
],
|
|
38
|
+
"dependencies": {
|
|
39
|
+
"@clack/prompts": "^1.0.1",
|
|
40
|
+
"@cosmjs/crypto": "^0.34.0",
|
|
41
|
+
"@cosmjs/encoding": "^0.34.0",
|
|
42
|
+
"@cosmjs/proto-signing": "^0.34.0",
|
|
43
|
+
"@ixo/impactxclient-sdk": "^2.4.1",
|
|
44
|
+
"@ixo/matrixclient-sdk": "^1.0.0",
|
|
45
|
+
"@ixo/signx-sdk": "^1.2.0",
|
|
46
|
+
"@matrix-org/matrix-sdk-crypto-wasm": "^15.1.0",
|
|
47
|
+
"eciesjs": "^0.4.15",
|
|
48
|
+
"loglevel": "^1.9.2",
|
|
49
|
+
"matrix-js-sdk": "^37.12.0",
|
|
50
|
+
"md5": "^2.3.0",
|
|
51
|
+
"multiformats": "^13.3.7",
|
|
52
|
+
"node-fetch": "^3.3.2",
|
|
53
|
+
"qrcode-terminal": "^0.12.0",
|
|
54
|
+
"simple-git": "^3.28.0",
|
|
55
|
+
"zod": "^4.0.14"
|
|
56
|
+
},
|
|
57
|
+
"devDependencies": {
|
|
58
|
+
"@types/jest": "^29.5.0",
|
|
59
|
+
"@types/md5": "^2.3.5",
|
|
60
|
+
"@types/node": "^22.0.0",
|
|
61
|
+
"@types/qrcode-terminal": "^0.12.2",
|
|
62
|
+
"@typescript-eslint/eslint-plugin": "^8.39.0",
|
|
63
|
+
"@typescript-eslint/parser": "^8.39.0",
|
|
64
|
+
"eslint": "^8.57.0",
|
|
65
|
+
"jest": "^29.7.0",
|
|
66
|
+
"ts-jest": "^29.1.0",
|
|
67
|
+
"tsup": "^8.0.2",
|
|
68
|
+
"typescript": "^5.4.0"
|
|
69
|
+
},
|
|
70
|
+
"scripts": {
|
|
71
|
+
"build": "tsup",
|
|
72
|
+
"dev": "tsup --watch",
|
|
73
|
+
"start": "node dist/cli.js",
|
|
74
|
+
"test": "jest",
|
|
75
|
+
"lint": "eslint src/**/*.ts",
|
|
76
|
+
"lint:fix": "eslint src/**/*.ts --fix",
|
|
77
|
+
"type-check": "tsc --noEmit"
|
|
78
|
+
}
|
|
79
|
+
}
|