@ftptech/canton-agent-wallet 0.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 +201 -0
- package/README.md +134 -0
- package/dist/canton-hash.d.ts +61 -0
- package/dist/canton-hash.d.ts.map +1 -0
- package/dist/canton-hash.js +108 -0
- package/dist/canton-hash.js.map +1 -0
- package/dist/cli-args.d.ts +31 -0
- package/dist/cli-args.d.ts.map +1 -0
- package/dist/cli-args.js +56 -0
- package/dist/cli-args.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +123 -0
- package/dist/cli.js.map +1 -0
- package/dist/hash-binding.d.ts +40 -0
- package/dist/hash-binding.d.ts.map +1 -0
- package/dist/hash-binding.js +20 -0
- package/dist/hash-binding.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +13 -0
- package/dist/index.js.map +1 -0
- package/dist/keys.d.ts +26 -0
- package/dist/keys.d.ts.map +1 -0
- package/dist/keys.js +38 -0
- package/dist/keys.js.map +1 -0
- package/dist/onboard.d.ts +12 -0
- package/dist/onboard.d.ts.map +1 -0
- package/dist/onboard.js +152 -0
- package/dist/onboard.js.map +1 -0
- package/dist/pay.d.ts +16 -0
- package/dist/pay.d.ts.map +1 -0
- package/dist/pay.js +19 -0
- package/dist/pay.js.map +1 -0
- package/dist/relay-client.d.ts +128 -0
- package/dist/relay-client.d.ts.map +1 -0
- package/dist/relay-client.js +67 -0
- package/dist/relay-client.js.map +1 -0
- package/dist/relay-signer.d.ts +33 -0
- package/dist/relay-signer.d.ts.map +1 -0
- package/dist/relay-signer.js +44 -0
- package/dist/relay-signer.js.map +1 -0
- package/dist/store.d.ts +15 -0
- package/dist/store.d.ts.map +1 -0
- package/dist/store.js +33 -0
- package/dist/store.js.map +1 -0
- package/dist/trusted-dso.d.ts +33 -0
- package/dist/trusted-dso.d.ts.map +1 -0
- package/dist/trusted-dso.js +36 -0
- package/dist/trusted-dso.js.map +1 -0
- package/dist/tx.d.ts +102 -0
- package/dist/tx.d.ts.map +1 -0
- package/dist/tx.js +328 -0
- package/dist/tx.js.map +1 -0
- package/dist/verify-prepared.d.ts +361 -0
- package/dist/verify-prepared.d.ts.map +1 -0
- package/dist/verify-prepared.js +2235 -0
- package/dist/verify-prepared.js.map +1 -0
- package/dist/withdraw.d.ts +18 -0
- package/dist/withdraw.d.ts.map +1 -0
- package/dist/withdraw.js +31 -0
- package/dist/withdraw.js.map +1 -0
- package/package.json +33 -0
package/LICENSE
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 describing the origin of the Work and
|
|
141
|
+
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 Support. 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 support.
|
|
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 2026 FTP Team
|
|
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,134 @@
|
|
|
1
|
+
# @ftptech/canton-agent-wallet
|
|
2
|
+
|
|
3
|
+
A self-custody Canton wallet + x402 autopay for AI agents. The agent holds its
|
|
4
|
+
own Ed25519 key and pays for x402-gated resources on the Canton Network on its
|
|
5
|
+
own — the hard parts of Canton (a party must be hosted on a validator, and its
|
|
6
|
+
API is authed) are hidden behind a facilitator **relay** the agent talks to over
|
|
7
|
+
plain HTTP. The relay can *prepare* and *submit* on the agent's behalf but never
|
|
8
|
+
*signs*, so it has no custody.
|
|
9
|
+
|
|
10
|
+
Backs the [`canton-x402-agent`](../../skills/canton-x402-agent/SKILL.md) skill.
|
|
11
|
+
|
|
12
|
+
## Install
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
npm install @ftptech/canton-agent-wallet
|
|
16
|
+
# or run the CLI without installing:
|
|
17
|
+
npx @ftptech/canton-agent-wallet <command>
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Bin: `canton-agent-wallet`.
|
|
21
|
+
|
|
22
|
+
## CLI
|
|
23
|
+
|
|
24
|
+
```
|
|
25
|
+
canton-agent-wallet create --relay-url <url> # generate + onboard a self-custody wallet (idempotent)
|
|
26
|
+
canton-agent-wallet address # print the party id (fund this)
|
|
27
|
+
canton-agent-wallet balance # print CC balance
|
|
28
|
+
canton-agent-wallet claim # accept incoming transfers (e.g. the initial funding)
|
|
29
|
+
canton-agent-wallet pay --relay-url <url> <url> # fetch a URL, auto-paying any x402 402 challenge
|
|
30
|
+
canton-agent-wallet withdraw --to <party> [--amount <cc>] # send CC back out (default: full balance)
|
|
31
|
+
canton-agent-wallet export # print the private key (backup; guard it)
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
`create` and `pay` **require** a relay (facilitator) URL — pass `--relay-url
|
|
35
|
+
<url>` or set `CANTON_AGENT_RELAY_URL`. There is no default: a stale built-in
|
|
36
|
+
default would silently send payments to a dead host, so the CLI fails fast when
|
|
37
|
+
none is given. `address`, `balance`, `claim`, `withdraw` and `export` reuse the
|
|
38
|
+
relay stored in the wallet at `create` time. The current FTP facilitator is
|
|
39
|
+
`http://46.225.91.251:4022` (plain HTTP by IP; a TLS domain is not yet live).
|
|
40
|
+
|
|
41
|
+
On Canton, incoming CC arrives as a **pending transfer** the agent must accept,
|
|
42
|
+
so the first-run flow is:
|
|
43
|
+
`create --relay-url http://46.225.91.251:4022` → tell your human to send CC to
|
|
44
|
+
the printed party id → `claim` → `balance`. Funding once is the only human step,
|
|
45
|
+
exactly like funding an EVM agent.
|
|
46
|
+
|
|
47
|
+
## Programmatic API
|
|
48
|
+
|
|
49
|
+
`makePayingFetch()` returns a `fetch` that transparently pays x402 challenges
|
|
50
|
+
from the agent's wallet (lazily creating the wallet on first use):
|
|
51
|
+
|
|
52
|
+
```ts
|
|
53
|
+
import { makePayingFetch } from "@ftptech/canton-agent-wallet";
|
|
54
|
+
|
|
55
|
+
const fetch = await makePayingFetch({
|
|
56
|
+
relayUrl: process.env.CANTON_AGENT_RELAY_URL,
|
|
57
|
+
network: "canton:testnet",
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
const res = await fetch("https://paid.api/resource"); // 402 -> pay -> retry, transparently
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
On a 402 it resolves the transfer factory via the relay, builds the CIP-56
|
|
64
|
+
transfer, signs the prepared-transaction hash locally, has the relay submit it,
|
|
65
|
+
then retries the request with the on-ledger proof.
|
|
66
|
+
|
|
67
|
+
## Config (env)
|
|
68
|
+
|
|
69
|
+
- `CANTON_AGENT_RELAY_URL` — facilitator relay base URL. **Required** for the
|
|
70
|
+
commands that talk to a relay (`create`, `pay`); there is intentionally no
|
|
71
|
+
built-in default (a stale default would silently send payments to a dead
|
|
72
|
+
host). Supply it here or via `--relay-url <url>`. The current FTP facilitator
|
|
73
|
+
is `http://46.225.91.251:4022` (plain HTTP, by IP — a TLS domain such as
|
|
74
|
+
`facilitator.ftptech.xyz` is planned but not yet live).
|
|
75
|
+
- `CANTON_AGENT_NETWORK` — `canton:testnet` (default) or `canton:mainnet`; also
|
|
76
|
+
settable via `--network <net>`.
|
|
77
|
+
- `CANTON_AGENT_API_KEY` — only if the relay requires one (sent as the
|
|
78
|
+
`X-Agent-Key` header).
|
|
79
|
+
- `CANTON_AGENT_HOME` — override the wallet directory (default `~/.canton-agent`;
|
|
80
|
+
used by tests and power users).
|
|
81
|
+
|
|
82
|
+
## Your wallet is YOURS (self-custody)
|
|
83
|
+
|
|
84
|
+
The wallet lives at `~/.canton-agent/wallet.json` (mode `0600`). **This file IS
|
|
85
|
+
your money — back it up.** Losing it loses the funds. The agent reuses the same
|
|
86
|
+
wallet forever and never silently creates a second one. The validator only
|
|
87
|
+
*hosts* your party; it can never spend your CC — only your signature authorizes a
|
|
88
|
+
transfer. `canton-agent-wallet export` prints the private key for backup or
|
|
89
|
+
import.
|
|
90
|
+
|
|
91
|
+
## How it works
|
|
92
|
+
|
|
93
|
+
Self-custody external party per **CIP-0103**: you generate and hold the Ed25519
|
|
94
|
+
key; the facilitator relay bridges onboarding and submission to the Canton
|
|
95
|
+
participant using the validator's auth, so you need no Canton account.
|
|
96
|
+
|
|
97
|
+
- **Onboard:** the relay runs `generate-topology`; the agent signs the returned
|
|
98
|
+
multi-hash locally; the relay allocates the party.
|
|
99
|
+
- **Pay / withdraw:** the relay prepares the transaction (and proxies the public
|
|
100
|
+
Scan registry resolves the agent can't reach); the agent **verifies the
|
|
101
|
+
prepared transaction matches its intent and binds the hash to those exact
|
|
102
|
+
bytes** before signing; the relay only forwards the signed submission.
|
|
103
|
+
|
|
104
|
+
Every state-changing operation is authorized by the agent's signature.
|
|
105
|
+
|
|
106
|
+
### Verify-before-sign and hash binding (fail-closed)
|
|
107
|
+
|
|
108
|
+
The relay is treated as untrusted. Before signing any transfer that moves funds,
|
|
109
|
+
the agent structurally decodes the relay-prepared transaction and checks the
|
|
110
|
+
sender / receiver / amount / instrument against its own intent (rejecting
|
|
111
|
+
ambiguous encodings that a spec-conformant parser would read differently). It
|
|
112
|
+
then **binds** the hash it signs to those validated bytes — because the Canton
|
|
113
|
+
Ledger API is explicit that "clients MUST recompute the hash from the raw
|
|
114
|
+
transaction if the preparing participant is not trusted". A compromised relay
|
|
115
|
+
that returns honest bytes paired with the hash of a different (tampered)
|
|
116
|
+
transaction is therefore rejected.
|
|
117
|
+
|
|
118
|
+
Binding requires one of:
|
|
119
|
+
|
|
120
|
+
- **`recomputeHash`** (programmatic): pass `hashBinding: { recomputeHash }` to
|
|
121
|
+
`makePayingFetch` / `withdraw` / `transfer`, where `recomputeHash` reproduces
|
|
122
|
+
Canton's `HASHING_SCHEME_VERSION_V2` for the prepared bytes. This is the real
|
|
123
|
+
cryptographic binding.
|
|
124
|
+
- **`CANTON_AGENT_TRUST_RELAY_HASH=1`** (operator opt-in): accept the relay's
|
|
125
|
+
hash WITHOUT recomputation. This re-opens the blind-signing risk and is only
|
|
126
|
+
acceptable when a human reviews each transfer or the relay is fully trusted.
|
|
127
|
+
|
|
128
|
+
With neither configured, a value-moving transfer **refuses to sign** (fail-closed)
|
|
129
|
+
rather than blind-sign a relay-chosen hash. Accepting incoming transfers
|
|
130
|
+
(`claim`) needs no binding — no funds leave.
|
|
131
|
+
|
|
132
|
+
## License
|
|
133
|
+
|
|
134
|
+
Apache-2.0.
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Canton HashPurpose integers (4-byte big-endian domain-separation prefixes),
|
|
3
|
+
* confirmed against canonical Canton
|
|
4
|
+
* `community/base/.../crypto/HashPurpose.scala`. These are stable API: ids are
|
|
5
|
+
* eagerly-initialized and never reused.
|
|
6
|
+
*/
|
|
7
|
+
export declare const HASH_PURPOSE: {
|
|
8
|
+
/** Per onboarding/topology transaction hash. */
|
|
9
|
+
readonly TopologyTransactionSignature: 11;
|
|
10
|
+
/** Derive a public-key fingerprint (party namespace) from raw key bytes. */
|
|
11
|
+
readonly PublicKeyFingerprint: 12;
|
|
12
|
+
/** The combined multiHash over all topology transaction hashes. */
|
|
13
|
+
readonly MultiTopologyTransaction: 55;
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Recompute the prepared-transaction signing hash (Canton
|
|
17
|
+
* HASHING_SCHEME_VERSION_V2) from the EXACT base64 `preparedTransaction` the
|
|
18
|
+
* relay returns from `POST /v1/wallet/submit/prepare`, returning it base64.
|
|
19
|
+
*
|
|
20
|
+
* This is hash (1): a Merkle hash over the Daml transaction node tree, returned
|
|
21
|
+
* as the raw 32 bytes (NOT multihash-framed) base64-encoded — exactly what the
|
|
22
|
+
* relay returns as `hash`. Compare base64-to-base64; sign the RECOMPUTED value.
|
|
23
|
+
*
|
|
24
|
+
* Async: `hashPreparedTransaction` uses WebCrypto (`crypto.subtle.digest`).
|
|
25
|
+
*/
|
|
26
|
+
export declare function recomputeHash(preparedTransactionB64: string): Promise<string>;
|
|
27
|
+
/**
|
|
28
|
+
* Recompute the onboarding topology multiHash (hash (2)) from the array of
|
|
29
|
+
* base64 `onboardingTransactions` the relay returns from
|
|
30
|
+
* `POST /v1/wallet/onboard/prepare`, returning it base64 to compare against the
|
|
31
|
+
* relay's `hashToSign`.
|
|
32
|
+
*
|
|
33
|
+
* Algorithm (spec A.3 / B.4), 4-line wrapper over the library primitives:
|
|
34
|
+
* h_i = computeSha256CantonHash(11, raw_i) // per-tx, 34B framed
|
|
35
|
+
* combined = computeMultiHashForTopology([h_0, h_1..]) // sorted-by-hex, framed
|
|
36
|
+
* multiHash= computeSha256CantonHash(55, combined) // combined, 34B framed
|
|
37
|
+
*
|
|
38
|
+
* The per-tx hash is over the RAW topology-transaction bytes as delivered (the
|
|
39
|
+
* hasher never decodes the proto), and `computeMultiHashForTopology` sorts the
|
|
40
|
+
* per-tx hashes by lowercase-hex ascending before combining — so the ORDER of
|
|
41
|
+
* `onboardingTransactions` does not matter. Both the per-tx hashes and the final
|
|
42
|
+
* multiHash are multihash-framed (0x12 0x20 prefix, 34 bytes); we compare the
|
|
43
|
+
* base64 verbatim and never strip the prefix.
|
|
44
|
+
*/
|
|
45
|
+
export declare function recomputeTopologyMultiHash(onboardingTxB64: string[]): Promise<string>;
|
|
46
|
+
/**
|
|
47
|
+
* Derive a Canton public-key fingerprint from raw public-key bytes:
|
|
48
|
+
* `hex( computeSha256CantonHash(12, publicKeyBytes) )` (spec B.5). The result is
|
|
49
|
+
* the multihash-framed (0x12 0x20 + 32 = 34 bytes) hash rendered as lowercase
|
|
50
|
+
* hex (68 chars) — the form Canton uses for the `publicKeyFingerprint` / party
|
|
51
|
+
* namespace.
|
|
52
|
+
*
|
|
53
|
+
* NOTE on which key-byte form to pass: Canton's fingerprint preimage is a
|
|
54
|
+
* specific serialization of the signing public key. Callers that need to match a
|
|
55
|
+
* relay-returned `publicKeyFingerprint` should try both the SPKI/DER bytes and
|
|
56
|
+
* the bare 32-byte Ed25519 point and keep the one that matches (see
|
|
57
|
+
* `onboard.ts`); this function is a pure transform over whatever bytes it is
|
|
58
|
+
* given, and the surrounding assert is fail-closed so a wrong guess refuses.
|
|
59
|
+
*/
|
|
60
|
+
export declare function fingerprintHex(publicKeyBytes: Uint8Array): Promise<string>;
|
|
61
|
+
//# sourceMappingURL=canton-hash.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"canton-hash.d.ts","sourceRoot":"","sources":["../src/canton-hash.ts"],"names":[],"mappings":"AAoCA;;;;;GAKG;AACH,eAAO,MAAM,YAAY;IACvB,gDAAgD;;IAEhD,4EAA4E;;IAE5E,mEAAmE;;CAE3D,CAAC;AAEX;;;;;;;;;;GAUG;AACH,wBAAgB,aAAa,CAAC,sBAAsB,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAE7E;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAsB,0BAA0B,CAC9C,eAAe,EAAE,MAAM,EAAE,GACxB,OAAO,CAAC,MAAM,CAAC,CAejB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,cAAc,CAClC,cAAc,EAAE,UAAU,GACzB,OAAO,CAAC,MAAM,CAAC,CAMjB"}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* canton-hash — the OFFICIAL Canton hash recompute, wired so the agent's
|
|
3
|
+
* Ed25519 signature is cryptographically bound to the bytes it verified.
|
|
4
|
+
*
|
|
5
|
+
* WHY THIS EXISTS
|
|
6
|
+
* ---------------
|
|
7
|
+
* The agent's self-custody guarantee has two independent legs (see
|
|
8
|
+
* verify-prepared.ts):
|
|
9
|
+
*
|
|
10
|
+
* 1. STRUCTURAL verify ("the bytes match my intent") — decode the relay's
|
|
11
|
+
* `PreparedTransaction` / topology bytes and pin receiver/amount/instrument
|
|
12
|
+
* (transfer) or own-key/own-namespace (onboarding) to caller intent.
|
|
13
|
+
* 2. HASH recompute ("I signed the bytes I saw") — recompute the signing hash
|
|
14
|
+
* from those exact bytes EXACTLY as the Canton participant does on
|
|
15
|
+
* `execute`/`allocate`, compare it to the relay-returned hash, and sign the
|
|
16
|
+
* RECOMPUTED value. This defeats a relay that returns structurally-honest
|
|
17
|
+
* bytes paired with the hash of a DIFFERENT transaction (then forwards the
|
|
18
|
+
* different bytes to the participant).
|
|
19
|
+
*
|
|
20
|
+
* Leg 2 was missing — `hash-binding.ts` was fail-closed with no conformant
|
|
21
|
+
* recompute. This module supplies it by delegating to the official, published,
|
|
22
|
+
* Apache-2.0 `@canton-network/core-tx-visualizer` (the same code the rest of the
|
|
23
|
+
* Canton wallet ecosystem signs with), so the bytes-exact V2 algorithm is the
|
|
24
|
+
* library's problem, not a hand-reimplementation's. The conformance test
|
|
25
|
+
* (`canton-hash.conformance.test.ts`) gates trusting it against live vectors.
|
|
26
|
+
*
|
|
27
|
+
* We deliberately do NOT use the SDK's `sign()` — it signs the relay-returned
|
|
28
|
+
* hash directly with no recompute/compare, which would reproduce the blind-sign
|
|
29
|
+
* bug. We use the library only for HASHING and keep our own compare-then-sign.
|
|
30
|
+
*/
|
|
31
|
+
import { hashPreparedTransaction, computeSha256CantonHash, computeMultiHashForTopology, } from "@canton-network/core-tx-visualizer";
|
|
32
|
+
/**
|
|
33
|
+
* Canton HashPurpose integers (4-byte big-endian domain-separation prefixes),
|
|
34
|
+
* confirmed against canonical Canton
|
|
35
|
+
* `community/base/.../crypto/HashPurpose.scala`. These are stable API: ids are
|
|
36
|
+
* eagerly-initialized and never reused.
|
|
37
|
+
*/
|
|
38
|
+
export const HASH_PURPOSE = {
|
|
39
|
+
/** Per onboarding/topology transaction hash. */
|
|
40
|
+
TopologyTransactionSignature: 11,
|
|
41
|
+
/** Derive a public-key fingerprint (party namespace) from raw key bytes. */
|
|
42
|
+
PublicKeyFingerprint: 12,
|
|
43
|
+
/** The combined multiHash over all topology transaction hashes. */
|
|
44
|
+
MultiTopologyTransaction: 55,
|
|
45
|
+
};
|
|
46
|
+
/**
|
|
47
|
+
* Recompute the prepared-transaction signing hash (Canton
|
|
48
|
+
* HASHING_SCHEME_VERSION_V2) from the EXACT base64 `preparedTransaction` the
|
|
49
|
+
* relay returns from `POST /v1/wallet/submit/prepare`, returning it base64.
|
|
50
|
+
*
|
|
51
|
+
* This is hash (1): a Merkle hash over the Daml transaction node tree, returned
|
|
52
|
+
* as the raw 32 bytes (NOT multihash-framed) base64-encoded — exactly what the
|
|
53
|
+
* relay returns as `hash`. Compare base64-to-base64; sign the RECOMPUTED value.
|
|
54
|
+
*
|
|
55
|
+
* Async: `hashPreparedTransaction` uses WebCrypto (`crypto.subtle.digest`).
|
|
56
|
+
*/
|
|
57
|
+
export function recomputeHash(preparedTransactionB64) {
|
|
58
|
+
return hashPreparedTransaction(preparedTransactionB64, "base64");
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Recompute the onboarding topology multiHash (hash (2)) from the array of
|
|
62
|
+
* base64 `onboardingTransactions` the relay returns from
|
|
63
|
+
* `POST /v1/wallet/onboard/prepare`, returning it base64 to compare against the
|
|
64
|
+
* relay's `hashToSign`.
|
|
65
|
+
*
|
|
66
|
+
* Algorithm (spec A.3 / B.4), 4-line wrapper over the library primitives:
|
|
67
|
+
* h_i = computeSha256CantonHash(11, raw_i) // per-tx, 34B framed
|
|
68
|
+
* combined = computeMultiHashForTopology([h_0, h_1..]) // sorted-by-hex, framed
|
|
69
|
+
* multiHash= computeSha256CantonHash(55, combined) // combined, 34B framed
|
|
70
|
+
*
|
|
71
|
+
* The per-tx hash is over the RAW topology-transaction bytes as delivered (the
|
|
72
|
+
* hasher never decodes the proto), and `computeMultiHashForTopology` sorts the
|
|
73
|
+
* per-tx hashes by lowercase-hex ascending before combining — so the ORDER of
|
|
74
|
+
* `onboardingTransactions` does not matter. Both the per-tx hashes and the final
|
|
75
|
+
* multiHash are multihash-framed (0x12 0x20 prefix, 34 bytes); we compare the
|
|
76
|
+
* base64 verbatim and never strip the prefix.
|
|
77
|
+
*/
|
|
78
|
+
export async function recomputeTopologyMultiHash(onboardingTxB64) {
|
|
79
|
+
const raw = await Promise.all(onboardingTxB64.map((b64) => computeSha256CantonHash(HASH_PURPOSE.TopologyTransactionSignature, bytesFromB64(b64))));
|
|
80
|
+
const combined = await computeMultiHashForTopology(raw);
|
|
81
|
+
const hash = await computeSha256CantonHash(HASH_PURPOSE.MultiTopologyTransaction, combined);
|
|
82
|
+
return Buffer.from(hash).toString("base64");
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Derive a Canton public-key fingerprint from raw public-key bytes:
|
|
86
|
+
* `hex( computeSha256CantonHash(12, publicKeyBytes) )` (spec B.5). The result is
|
|
87
|
+
* the multihash-framed (0x12 0x20 + 32 = 34 bytes) hash rendered as lowercase
|
|
88
|
+
* hex (68 chars) — the form Canton uses for the `publicKeyFingerprint` / party
|
|
89
|
+
* namespace.
|
|
90
|
+
*
|
|
91
|
+
* NOTE on which key-byte form to pass: Canton's fingerprint preimage is a
|
|
92
|
+
* specific serialization of the signing public key. Callers that need to match a
|
|
93
|
+
* relay-returned `publicKeyFingerprint` should try both the SPKI/DER bytes and
|
|
94
|
+
* the bare 32-byte Ed25519 point and keep the one that matches (see
|
|
95
|
+
* `onboard.ts`); this function is a pure transform over whatever bytes it is
|
|
96
|
+
* given, and the surrounding assert is fail-closed so a wrong guess refuses.
|
|
97
|
+
*/
|
|
98
|
+
export async function fingerprintHex(publicKeyBytes) {
|
|
99
|
+
const framed = await computeSha256CantonHash(HASH_PURPOSE.PublicKeyFingerprint, publicKeyBytes);
|
|
100
|
+
return Buffer.from(framed).toString("hex");
|
|
101
|
+
}
|
|
102
|
+
/** Decode a base64 string to bytes; throws on invalid base64-derived empties is
|
|
103
|
+
* left to the library's own digest (empty input still hashes). Kept tiny and
|
|
104
|
+
* dependency-free so the hash adapters stay pure. */
|
|
105
|
+
function bytesFromB64(b64) {
|
|
106
|
+
return Buffer.from(b64, "base64");
|
|
107
|
+
}
|
|
108
|
+
//# sourceMappingURL=canton-hash.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"canton-hash.js","sourceRoot":"","sources":["../src/canton-hash.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,OAAO,EACL,uBAAuB,EACvB,uBAAuB,EACvB,2BAA2B,GAC5B,MAAM,oCAAoC,CAAC;AAE5C;;;;;GAKG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B,gDAAgD;IAChD,4BAA4B,EAAE,EAAE;IAChC,4EAA4E;IAC5E,oBAAoB,EAAE,EAAE;IACxB,mEAAmE;IACnE,wBAAwB,EAAE,EAAE;CACpB,CAAC;AAEX;;;;;;;;;;GAUG;AACH,MAAM,UAAU,aAAa,CAAC,sBAA8B;IAC1D,OAAO,uBAAuB,CAAC,sBAAsB,EAAE,QAAQ,CAAC,CAAC;AACnE,CAAC;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,CAAC,KAAK,UAAU,0BAA0B,CAC9C,eAAyB;IAEzB,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,GAAG,CAC3B,eAAe,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAC1B,uBAAuB,CACrB,YAAY,CAAC,4BAA4B,EACzC,YAAY,CAAC,GAAG,CAAC,CAClB,CACF,CACF,CAAC;IACF,MAAM,QAAQ,GAAG,MAAM,2BAA2B,CAAC,GAAG,CAAC,CAAC;IACxD,MAAM,IAAI,GAAG,MAAM,uBAAuB,CACxC,YAAY,CAAC,wBAAwB,EACrC,QAAQ,CACT,CAAC;IACF,OAAO,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;AAC9C,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,cAA0B;IAE1B,MAAM,MAAM,GAAG,MAAM,uBAAuB,CAC1C,YAAY,CAAC,oBAAoB,EACjC,cAAc,CACf,CAAC;IACF,OAAO,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;AAC7C,CAAC;AAED;;sDAEsD;AACtD,SAAS,YAAY,CAAC,GAAW;IAC/B,OAAO,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;AACpC,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure (side-effect-free) argument helpers for the canton-agent-wallet CLI.
|
|
3
|
+
*
|
|
4
|
+
* Kept in their own module so they can be unit-tested without importing
|
|
5
|
+
* `cli.ts` (which auto-runs `main()` on import and would call
|
|
6
|
+
* `process.exit`). `cli.ts` composes these with its env + `fail()`.
|
|
7
|
+
*/
|
|
8
|
+
export declare const DEFAULT_NETWORK = "canton:testnet";
|
|
9
|
+
/** Known `--flag <value>` options; used to strip flags out of positionals. */
|
|
10
|
+
export declare const VALUE_FLAGS: ReadonlySet<string>;
|
|
11
|
+
/** First value following `--<name>` in `args`, or undefined. */
|
|
12
|
+
export declare function flag(args: readonly string[], name: string): string | undefined;
|
|
13
|
+
/**
|
|
14
|
+
* Positional args with any known `--flag <value>` pairs removed, so a command
|
|
15
|
+
* can read its positional (e.g. `pay <url>`) regardless of where the flags
|
|
16
|
+
* were placed on the line. A trailing `--flag` with no value still consumes
|
|
17
|
+
* the (missing) value slot, matching `flag()`'s lookahead.
|
|
18
|
+
*/
|
|
19
|
+
export declare function positionals(args: readonly string[]): string[];
|
|
20
|
+
/**
|
|
21
|
+
* Resolve the relay (facilitator) URL: `--relay-url` flag wins, else the
|
|
22
|
+
* CANTON_AGENT_RELAY_URL env var. There is intentionally NO default — a
|
|
23
|
+
* stale built-in default silently sends an agent's payments to a dead host,
|
|
24
|
+
* so the caller must fail fast when this returns undefined.
|
|
25
|
+
*/
|
|
26
|
+
export declare function resolveRelayUrl(args: readonly string[], env?: NodeJS.ProcessEnv): string | undefined;
|
|
27
|
+
/** Network: `--network` flag wins, else CANTON_AGENT_NETWORK, else testnet. */
|
|
28
|
+
export declare function resolveNetwork(args: readonly string[], env?: NodeJS.ProcessEnv): string;
|
|
29
|
+
/** Message shown when no relay URL is supplied (flag or env). */
|
|
30
|
+
export declare const MISSING_RELAY_HELP: string;
|
|
31
|
+
//# sourceMappingURL=cli-args.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli-args.d.ts","sourceRoot":"","sources":["../src/cli-args.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,eAAO,MAAM,eAAe,mBAAmB,CAAC;AAEhD,8EAA8E;AAC9E,eAAO,MAAM,WAAW,EAAE,WAAW,CAAC,MAAM,CAK1C,CAAC;AAEH,gEAAgE;AAChE,wBAAgB,IAAI,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAG9E;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,EAAE,CAW7D;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAC7B,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,GAAG,GAAE,MAAM,CAAC,UAAwB,GACnC,MAAM,GAAG,SAAS,CAEpB;AAED,+EAA+E;AAC/E,wBAAgB,cAAc,CAC5B,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,GAAG,GAAE,MAAM,CAAC,UAAwB,GACnC,MAAM,CAER;AAED,iEAAiE;AACjE,eAAO,MAAM,kBAAkB,QAGwD,CAAC"}
|
package/dist/cli-args.js
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure (side-effect-free) argument helpers for the canton-agent-wallet CLI.
|
|
3
|
+
*
|
|
4
|
+
* Kept in their own module so they can be unit-tested without importing
|
|
5
|
+
* `cli.ts` (which auto-runs `main()` on import and would call
|
|
6
|
+
* `process.exit`). `cli.ts` composes these with its env + `fail()`.
|
|
7
|
+
*/
|
|
8
|
+
export const DEFAULT_NETWORK = "canton:testnet";
|
|
9
|
+
/** Known `--flag <value>` options; used to strip flags out of positionals. */
|
|
10
|
+
export const VALUE_FLAGS = new Set([
|
|
11
|
+
"--relay-url",
|
|
12
|
+
"--network",
|
|
13
|
+
"--to",
|
|
14
|
+
"--amount",
|
|
15
|
+
]);
|
|
16
|
+
/** First value following `--<name>` in `args`, or undefined. */
|
|
17
|
+
export function flag(args, name) {
|
|
18
|
+
const i = args.indexOf(name);
|
|
19
|
+
return i >= 0 && i + 1 < args.length ? args[i + 1] : undefined;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Positional args with any known `--flag <value>` pairs removed, so a command
|
|
23
|
+
* can read its positional (e.g. `pay <url>`) regardless of where the flags
|
|
24
|
+
* were placed on the line. A trailing `--flag` with no value still consumes
|
|
25
|
+
* the (missing) value slot, matching `flag()`'s lookahead.
|
|
26
|
+
*/
|
|
27
|
+
export function positionals(args) {
|
|
28
|
+
const out = [];
|
|
29
|
+
for (let i = 0; i < args.length; i += 1) {
|
|
30
|
+
const a = args[i];
|
|
31
|
+
if (VALUE_FLAGS.has(a)) {
|
|
32
|
+
i += 1; // skip this flag's value
|
|
33
|
+
continue;
|
|
34
|
+
}
|
|
35
|
+
out.push(a);
|
|
36
|
+
}
|
|
37
|
+
return out;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Resolve the relay (facilitator) URL: `--relay-url` flag wins, else the
|
|
41
|
+
* CANTON_AGENT_RELAY_URL env var. There is intentionally NO default — a
|
|
42
|
+
* stale built-in default silently sends an agent's payments to a dead host,
|
|
43
|
+
* so the caller must fail fast when this returns undefined.
|
|
44
|
+
*/
|
|
45
|
+
export function resolveRelayUrl(args, env = process.env) {
|
|
46
|
+
return flag(args, "--relay-url") || env.CANTON_AGENT_RELAY_URL || undefined;
|
|
47
|
+
}
|
|
48
|
+
/** Network: `--network` flag wins, else CANTON_AGENT_NETWORK, else testnet. */
|
|
49
|
+
export function resolveNetwork(args, env = process.env) {
|
|
50
|
+
return flag(args, "--network") || env.CANTON_AGENT_NETWORK || DEFAULT_NETWORK;
|
|
51
|
+
}
|
|
52
|
+
/** Message shown when no relay URL is supplied (flag or env). */
|
|
53
|
+
export const MISSING_RELAY_HELP = "no relay URL — pass --relay-url <url> or set CANTON_AGENT_RELAY_URL.\n" +
|
|
54
|
+
" e.g. canton-agent-wallet create --relay-url http://46.225.91.251:4022\n" +
|
|
55
|
+
" (the FTP facilitator is currently plain HTTP by IP; a TLS domain is not yet live)";
|
|
56
|
+
//# sourceMappingURL=cli-args.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli-args.js","sourceRoot":"","sources":["../src/cli-args.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,CAAC,MAAM,eAAe,GAAG,gBAAgB,CAAC;AAEhD,8EAA8E;AAC9E,MAAM,CAAC,MAAM,WAAW,GAAwB,IAAI,GAAG,CAAC;IACtD,aAAa;IACb,WAAW;IACX,MAAM;IACN,UAAU;CACX,CAAC,CAAC;AAEH,gEAAgE;AAChE,MAAM,UAAU,IAAI,CAAC,IAAuB,EAAE,IAAY;IACxD,MAAM,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7B,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AACjE,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,WAAW,CAAC,IAAuB;IACjD,MAAM,GAAG,GAAa,EAAE,CAAC;IACzB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QACxC,MAAM,CAAC,GAAG,IAAI,CAAC,CAAC,CAAW,CAAC;QAC5B,IAAI,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;YACvB,CAAC,IAAI,CAAC,CAAC,CAAC,yBAAyB;YACjC,SAAS;QACX,CAAC;QACD,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACd,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,eAAe,CAC7B,IAAuB,EACvB,MAAyB,OAAO,CAAC,GAAG;IAEpC,OAAO,IAAI,CAAC,IAAI,EAAE,aAAa,CAAC,IAAI,GAAG,CAAC,sBAAsB,IAAI,SAAS,CAAC;AAC9E,CAAC;AAED,+EAA+E;AAC/E,MAAM,UAAU,cAAc,CAC5B,IAAuB,EACvB,MAAyB,OAAO,CAAC,GAAG;IAEpC,OAAO,IAAI,CAAC,IAAI,EAAE,WAAW,CAAC,IAAI,GAAG,CAAC,oBAAoB,IAAI,eAAe,CAAC;AAChF,CAAC;AAED,iEAAiE;AACjE,MAAM,CAAC,MAAM,kBAAkB,GAC7B,wEAAwE;IACxE,2EAA2E;IAC3E,qFAAqF,CAAC"}
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
|