@kuiralabs/midnight-account-chain 0.0.0-stage → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/README.md +300 -2
- package/dist/cli/owner.d.ts +3 -0
- package/dist/cli/owner.js +260 -0
- package/dist/driver.d.ts +34 -0
- package/dist/driver.js +121 -0
- package/dist/managed/Account/compiler/contract-info.json +5712 -0
- package/dist/managed/Account/compiler/contract-manifest.json +639 -0
- package/dist/managed/Account/contract/index.d.ts +1688 -0
- package/dist/managed/Account/contract/index.js +12892 -0
- package/dist/managed/Account/contract/index.js.map +8 -0
- package/dist/scripts/completeDeploy.d.ts +2 -0
- package/dist/scripts/completeDeploy.js +42 -0
- package/dist/scripts/deploy.d.ts +9 -0
- package/dist/scripts/deploy.js +136 -0
- package/dist/src/account.d.ts +17 -0
- package/dist/src/account.js +25 -0
- package/dist/src/agent.d.ts +58 -0
- package/dist/src/agent.js +279 -0
- package/dist/src/artefacts.d.ts +13 -0
- package/dist/src/artefacts.js +257 -0
- package/dist/src/coins.d.ts +25 -0
- package/dist/src/coins.js +159 -0
- package/dist/src/compose.d.ts +11 -0
- package/dist/src/compose.js +90 -0
- package/dist/src/connect.d.ts +18 -0
- package/dist/src/connect.js +37 -0
- package/dist/src/deposit.d.ts +6 -0
- package/dist/src/deposit.js +13 -0
- package/dist/src/device.d.ts +25 -0
- package/dist/src/device.js +50 -0
- package/dist/src/grantee.d.ts +32 -0
- package/dist/src/grantee.js +45 -0
- package/dist/src/indexer.d.ts +2 -0
- package/dist/src/indexer.js +89 -0
- package/dist/src/issuance.d.ts +36 -0
- package/dist/src/issuance.js +349 -0
- package/dist/src/localnet.d.ts +16 -0
- package/dist/src/localnet.js +50 -0
- package/dist/src/mailbox.d.ts +9 -0
- package/dist/src/mailbox.js +44 -0
- package/dist/src/maintenance.d.ts +13 -0
- package/dist/src/maintenance.js +100 -0
- package/dist/src/ownerCalls.d.ts +19 -0
- package/dist/src/ownerCalls.js +106 -0
- package/dist/src/profile.d.ts +10 -0
- package/dist/src/profile.js +73 -0
- package/dist/src/providers.d.ts +11 -0
- package/dist/src/providers.js +33 -0
- package/dist/src/reader.d.ts +31 -0
- package/dist/src/reader.js +73 -0
- package/dist/src/seedWallets.d.ts +75 -0
- package/dist/src/seedWallets.js +31 -0
- package/dist/src/session.d.ts +47 -0
- package/dist/src/session.js +133 -0
- package/package.json +50 -4
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 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 {yyyy} {name of copyright owner}
|
|
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
CHANGED
|
@@ -1,3 +1,301 @@
|
|
|
1
|
-
#
|
|
1
|
+
# chain
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
The account contract on a local ledger-9 network. This package builds the same
|
|
4
|
+
`../account/contract/Account.compact` as the library, with Compact 0.35.0 in place
|
|
5
|
+
of 0.34.0. The reason is the SDK: midnight-js 5.0.0-rc.1 and the wallet SDK
|
|
6
|
+
2.0.0-rc.0 run on compact-runtime 0.20.0, which only a 0.35.0 build targets.
|
|
7
|
+
The library keeps 0.34.0, because OpenZeppelin's simulator is still on
|
|
8
|
+
runtime 0.19.0.
|
|
9
|
+
|
|
10
|
+
## The stack
|
|
11
|
+
|
|
12
|
+
Every component is on ledger 9.1.0.0-rc.5:
|
|
13
|
+
|
|
14
|
+
| Component | Version |
|
|
15
|
+
|---|---|
|
|
16
|
+
| Compact | 0.35.0 (runtime 0.20.0) |
|
|
17
|
+
| midnight-js | 5.0.0-rc.1, with testkit-js 5.0.0-rc.1 |
|
|
18
|
+
| Wallet SDK | `@midnightntwrk/wallet-sdk` 2.0.0-rc.0 |
|
|
19
|
+
| Node | `midnightntwrk/midnight-node:2.1.0-rc.2` |
|
|
20
|
+
| Indexer | built from midnight-indexer main at `3e9f6374` |
|
|
21
|
+
| Proof server | `midnightntwrk/proof-server:9.0.0-rc.8` |
|
|
22
|
+
|
|
23
|
+
The public networks (Preview, Preprod) still run ledger 8. Midnight's
|
|
24
|
+
compatibility matrix does not cover ledger 9 yet.
|
|
25
|
+
|
|
26
|
+
The indexer has to be built from source:
|
|
27
|
+
- Every published ledger-9 indexer image is 4.4.0-rc.2, which is on ledger rc.3.
|
|
28
|
+
- Newer indexers exist only as source.
|
|
29
|
+
|
|
30
|
+
Node 2.1.0-rc.2 is the newest node version the indexer carries metadata for.
|
|
31
|
+
|
|
32
|
+
## Running
|
|
33
|
+
|
|
34
|
+
Build the indexer image once. Use the release profile, which is the Dockerfile's default:
|
|
35
|
+
|
|
36
|
+
```
|
|
37
|
+
git clone https://github.com/midnightntwrk/midnight-indexer && cd midnight-indexer
|
|
38
|
+
git checkout 3e9f6374
|
|
39
|
+
docker build --build-arg RUST_VERSION=$(sed -nr 's/channel = "(.*)"/\1/p' rust-toolchain.toml) \
|
|
40
|
+
-t midnight-bench/indexer-standalone:4.4.0-rc.5-3e9f6374 -f indexer-standalone/Dockerfile .
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Start the localnet. The indexer needs a 32-byte hex secret in `infra/.env`, which git ignores:
|
|
44
|
+
|
|
45
|
+
```
|
|
46
|
+
cd infra
|
|
47
|
+
echo "APP__INFRA__SECRET=$(openssl rand -hex 32)" > .env
|
|
48
|
+
docker compose up -d
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Compile with keys, then deploy:
|
|
52
|
+
|
|
53
|
+
```
|
|
54
|
+
npm install # after npm install in the repository root, which builds the library
|
|
55
|
+
npm run compile # 30 circuits, about 4 GB of proving keys
|
|
56
|
+
node scripts/deploy.ts
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## Deploying
|
|
60
|
+
|
|
61
|
+
The whole roster's verifier keys come to 73,806 bytes. A single deploy is
|
|
62
|
+
refused by the fee computation before any transaction exists: `exceeded block
|
|
63
|
+
limit in transaction fee computation`. The grants draft (section 6.7) measured
|
|
64
|
+
the same.
|
|
65
|
+
|
|
66
|
+
`scripts/deploy.ts` therefore deploys in waves:
|
|
67
|
+
1. **The deploy transaction.** It carries the two deposits and the eight
|
|
68
|
+
circuits of the arm the account is born on.
|
|
69
|
+
2. **Maintenance updates.** `src/maintenance.ts` adds every other circuit's key,
|
|
70
|
+
packed to 25,000 bytes per update. That is the draft's budget, below the
|
|
71
|
+
ceiling it measured between 29,484 and 32,229 bytes.
|
|
72
|
+
|
|
73
|
+
On this localnet that is four transactions in about 75 seconds. Then
|
|
74
|
+
midnight-js's own `findDeployedContract` checks every on-chain key against the build.
|
|
75
|
+
|
|
76
|
+
The maintenance updates are built by hand on the ledger-v9 API, not through
|
|
77
|
+
midnight-js's `submitInsertVerifierKeyTx`:
|
|
78
|
+
- compact-js, in every 3.0.0 release so far, wraps inserted keys at
|
|
79
|
+
contract-operation version `'v3'`, which expects a `verifier-key[v6]` header.
|
|
80
|
+
- A ZKIR v3 build writes `verifier-key[v7]`, which needs version `'v4'`.
|
|
81
|
+
- So the SDK path fails for any ZKIR v3 contract before a transaction exists.
|
|
82
|
+
- The update built here is the one compact-js builds, at the version the key
|
|
83
|
+
actually carries.
|
|
84
|
+
|
|
85
|
+
The last update also retires the maintenance authority (the grants draft,
|
|
86
|
+
section 6.7): it replaces the authority with an empty committee at threshold
|
|
87
|
+
1, which can sign nothing. After it, no one can change the contract's rules.
|
|
88
|
+
|
|
89
|
+
`scripts/completeDeploy.ts` resumes an interrupted deploy. It inserts only
|
|
90
|
+
the entry points that are still blank, and leaves a finished account as it
|
|
91
|
+
is.
|
|
92
|
+
|
|
93
|
+
The owner's key material is written to `.state/`, which git ignores:
|
|
94
|
+
- the JubJub device key
|
|
95
|
+
- the boot salt
|
|
96
|
+
- the X25519 account encryption key
|
|
97
|
+
|
|
98
|
+
The maintenance authority's key is written to the level private-state store in
|
|
99
|
+
`midnight-level-db/`.
|
|
100
|
+
|
|
101
|
+
## The account on chain
|
|
102
|
+
|
|
103
|
+
After the deploy, these scripts run the account's life as its parties see
|
|
104
|
+
it. Each one proves on the local proof server and submits to the node:
|
|
105
|
+
|
|
106
|
+
| Script | Who | What |
|
|
107
|
+
|---|---|---|
|
|
108
|
+
| `scripts/deploy.ts [v1 \| k1]` | owner | deploys an account born on a JubJub or a secp256k1 device key, in waves, and retires the authority |
|
|
109
|
+
| `scripts/activate.ts` | owner | activates the boot device, on either arm |
|
|
110
|
+
| `scripts/owner.ts` | owner | activates the boot device; the unshielded deposit it then tries is refused (below) |
|
|
111
|
+
| `scripts/depositShielded.ts` | anyone | `deposit_shielded`, with the InboxEntry sealed to `enc_key` read from chain |
|
|
112
|
+
| `scripts/discoverCoins.ts` | owner | the inbox walk (MIP-0012 section 6.5) |
|
|
113
|
+
| `scripts/ownerShielded.ts` | owner | a shielded withdrawal to the genesis wallet, then the change backfilled by `append_inbox` |
|
|
114
|
+
| `scripts/ownerPayContract.ts <payee>` | owner | pays another contract, composed with the payee's claim |
|
|
115
|
+
| `scripts/agentRequest.ts <account> [slot] [v1 \| k1] [payee contract]` | agent | a grant request: grantee key, X25519 read key, origin, slot, payee |
|
|
116
|
+
| `scripts/issueGrant.ts [seconds]` | owner | rotate before share, re-seal to the other live read grants, `issue_grant`, the sealed view |
|
|
117
|
+
| `scripts/agentSpend.ts [slot]` | agent | pays the merchant under the grant from its own wallet; an over-cap payment is refused |
|
|
118
|
+
| `scripts/agentPayContract.ts <slot> <payee>` | agent | pays a contract under a grant pinned to it, composed with the payee's claim |
|
|
119
|
+
| `scripts/admissionExpiry.ts <slot> [hold]` | agent | proves while live, holds, submits: refused after `expires_at`, included before it |
|
|
120
|
+
| `scripts/inFlight.ts <slot> <deposit \| revoke>` | agent | proves, then a deposit or a revocation lands, then submits: refused |
|
|
121
|
+
| `scripts/revokeGrant.ts <slot>` | owner | `revoke_grant`, then the rotation and re-seals section 8 item 6 asks |
|
|
122
|
+
| `scripts/revokeAllGrants.ts` | owner | `revoke_all_grants`, then the rotation |
|
|
123
|
+
| `scripts/agentStatus.ts [slot] [--mailbox-only]` | agent | what the agent sees of its grant, and where it learned it |
|
|
124
|
+
| `cli/owner.ts <command>` | owner | the owner's command line: `status`, `grants`, `issue <link> [--yes]`, `revoke <id \| slot>`, `revoke-all`, `revoke-exhausted [<id>...] [--yes]`, each with `--json` |
|
|
125
|
+
|
|
126
|
+
Each account is a profile (`src/profile.ts`). The first account's records
|
|
127
|
+
are in `.state/`. Another account is deployed and driven under its own
|
|
128
|
+
`BENCH_PROFILE`, with records in `.state/<profile>/`. For example, a
|
|
129
|
+
k1-born account:
|
|
130
|
+
|
|
131
|
+
```
|
|
132
|
+
BENCH_PROFILE=k1 node scripts/deploy.ts k1
|
|
133
|
+
BENCH_PROFILE=k1 node scripts/activate.ts
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
The owner's gated calls go through one API that picks the circuit of the
|
|
137
|
+
device's arm, `_with_jubjub` or `_with_k256` (`src/ownerCalls.ts`). The
|
|
138
|
+
agent's grant spends do the same by the grantee key's arm.
|
|
139
|
+
|
|
140
|
+
Four wallets take part: the owner pays from genesis seed `…01`, the agent
|
|
141
|
+
from `…02`, and the merchant is `…03`'s shielded address.
|
|
142
|
+
|
|
143
|
+
The owner's code also runs over a wallet it did not build. Anything that offers midnight-js's wallet and submit providers (`FeeWallet` in `src/providers.ts`; a wallet behind a DApp connector, say) can pay. Such a caller imports one module, `driver.ts`: `deployOver` deploys the account on the k1 arm and activates its boot device, on a device key the caller may bring, and is safe to run again (it completes a deploy that stopped part way, and moves aside the record of one that never reached the chain); `runOwnerOver` runs one of the owner's commands and hands back the result. The caller names its endpoints as URLs (`MIDNIGHT_ACCOUNT_NODE_URL`, `MIDNIGHT_ACCOUNT_INDEXER_URL`, `MIDNIGHT_ACCOUNT_PROOF_SERVER_URL`) and keeps its accounts' records outside the repo by naming a directory in `MIDNIGHT_ACCOUNT_STATE_DIR`; profiles live under it as they do under `.state/`.
|
|
144
|
+
|
|
145
|
+
Nothing is kept that the chain can give back:
|
|
146
|
+
- The owner's device use counter is recovered from the `devices` set.
|
|
147
|
+
- Both coin stores are rebuilt by the inbox walk on every session.
|
|
148
|
+
- The owner keeps every encryption secret it has held, so its walk reads the
|
|
149
|
+
whole inbox. A delegate holds only the current one.
|
|
150
|
+
|
|
151
|
+
### Coin discovery
|
|
152
|
+
|
|
153
|
+
The walk verifies each opened entry against the ledger's own `zswapOutput`
|
|
154
|
+
events for the account:
|
|
155
|
+
- The commitment is recomputed with the ledger's `runtimeCoinCommitment`.
|
|
156
|
+
- The event carries the coin's `mt_index`, so no position window or candidate
|
|
157
|
+
retry is needed.
|
|
158
|
+
- A coin is spent when its nullifier (`runtimeCoinNullifier`, with the
|
|
159
|
+
contract as sender) is among the account's `zswapInput` events.
|
|
160
|
+
|
|
161
|
+
`deposit_shielded` is permissionless, so the inbox can hold anything
|
|
162
|
+
192 bytes long. The walk skips any entry it cannot open, including one whose
|
|
163
|
+
ephemeral key is of low order, where the X25519 derivation itself fails. It
|
|
164
|
+
treats every such entry as inert noise (grants draft section 8 item 4), so no
|
|
165
|
+
depositor can stop the walk.
|
|
166
|
+
|
|
167
|
+
The events come from the indexer's `contractActions` subscription, which
|
|
168
|
+
lists a contract's transactions by address. MIP-0012 records that surface as
|
|
169
|
+
an ecosystem dependency; the indexer at `3e9f6374` has it.
|
|
170
|
+
|
|
171
|
+
### A grant, end to end
|
|
172
|
+
|
|
173
|
+
The draft's flow, with no step skipped:
|
|
174
|
+
1. **The agent's request** carries its grantee key, its read key and the
|
|
175
|
+
merchant's coin key.
|
|
176
|
+
2. **The owner** checks both keys (section 3.3, section 8 item 1), then
|
|
177
|
+
rotates before share (section 8 item 2):
|
|
178
|
+
- `rotate_enc_key_with_jubjub`
|
|
179
|
+
- one `append_inbox_with_jubjub` per held coin
|
|
180
|
+
- a re-seal of the new secret to every other live read grant
|
|
181
|
+
3. **The owner issues** the grant under the boot device and seals the new
|
|
182
|
+
secret to the read key in a 94-byte GrantViewSeal (section 8 item 3).
|
|
183
|
+
4. **The agent** opens the view and checks that `X25519(secret, 9)` is
|
|
184
|
+
`enc_key`. Then it walks the inbox and pays the merchant with
|
|
185
|
+
`withdraw_shielded_with_grant_jubjub`, sealing the change entry itself.
|
|
186
|
+
|
|
187
|
+
Neither party can lose track through a crash:
|
|
188
|
+
- **The owner** writes its roster before each step. A read grant is marked
|
|
189
|
+
for re-seal before a rotation blinds it; a new grant is written before it
|
|
190
|
+
is issued. The next run finishes what the last one left.
|
|
191
|
+
- **Interrupted issues.** One that landed is sealed on the next run. One
|
|
192
|
+
that left nothing on chain is kept as `issuing` while its transaction could
|
|
193
|
+
still land, an hour plus a margin by midnight-js's expiry, then marked
|
|
194
|
+
`abandoned`.
|
|
195
|
+
- **Unknown read grants.** A live read grant on chain that the roster holds
|
|
196
|
+
no key for is surfaced as requiring reconnection.
|
|
197
|
+
- **Re-seals** go only to the key the record's `read_pk_hash` names.
|
|
198
|
+
- **Rotation secrets** are written before the rotation is submitted, and
|
|
199
|
+
none is ever dropped.
|
|
200
|
+
- **Revocations.** A revocation records the rotation it owes before it is
|
|
201
|
+
submitted, so the rotation happens once, however many grants it revoked.
|
|
202
|
+
A revocation that never landed is retried, and its grant is never
|
|
203
|
+
re-sealed in the meantime.
|
|
204
|
+
- **Change coins** are recorded before the spend that creates them. Each
|
|
205
|
+
session open backfills any recorded change the chain created but no inbox
|
|
206
|
+
entry describes.
|
|
207
|
+
- **The use counter** is re-read from the `devices` set after every gated
|
|
208
|
+
call, whether or not the call landed.
|
|
209
|
+
- **The agent** keys its running spend by grant incarnation (the grant id
|
|
210
|
+
with `issued_at`), so a re-issued grant starts from zero. It records a
|
|
211
|
+
spend as pending before submitting it. Its
|
|
212
|
+
running spend is checked against the record's `spent_commit` on every
|
|
213
|
+
session and before every spend, and a pending spend is counted once that
|
|
214
|
+
commitment shows it landed.
|
|
215
|
+
|
|
216
|
+
Measured on this localnet, with one held coin:
|
|
217
|
+
- Issuing a read grant takes three transactions: rotation 48 s (two
|
|
218
|
+
transactions), then issue 24 s.
|
|
219
|
+
- Each grant spend takes about 30 s.
|
|
220
|
+
|
|
221
|
+
The runs check each outcome on chain:
|
|
222
|
+
- **Payment.** The merchant's coin is found by its commitment in the
|
|
223
|
+
transaction's events. The change is found by the agent's next walk.
|
|
224
|
+
- **Over the cap.** A payment that would exceed the cap fails the circuit's
|
|
225
|
+
own assert before any proof exists.
|
|
226
|
+
- **Admission expiry.** A spend proved while the grant is live and held
|
|
227
|
+
173 s is included if submitted before `expires_at`. Submitted after it,
|
|
228
|
+
the node refuses it from the mempool, with custom error 104: `guaranteed
|
|
229
|
+
execution would fail: mismatch between expected (<[01]: b1>) and actual
|
|
230
|
+
(<[-]: b1>) read`. The proof recorded the block-time comparison as true;
|
|
231
|
+
at admission it reads false. The record's nonce and the coin are untouched.
|
|
232
|
+
|
|
233
|
+
### The grant mailbox
|
|
234
|
+
|
|
235
|
+
The owner's response to a grant request travels on chain, sealed to the
|
|
236
|
+
agent's read key (`../src/grants/mailbox.ts`, `src/mailbox.ts`):
|
|
237
|
+
- **What it is.** Two `append_inbox` entries carry the scope's salt and
|
|
238
|
+
object, its `rp_id_hash`, and the account secret.
|
|
239
|
+
- **Finding it.** The agent computes its grant id, walks the inbox with its
|
|
240
|
+
read key, and checks the message against the record's commitments and
|
|
241
|
+
`enc_key`.
|
|
242
|
+
- **Re-seals.** After a rotation they arrive the same way, so the agent
|
|
243
|
+
picks up the new secret by reading the chain again.
|
|
244
|
+
- **Fallback.** The owner also writes the same sealed message as a response
|
|
245
|
+
file, and `cli/owner.ts issue` prints it as a link for a QR code. Nothing
|
|
246
|
+
in it is in clear, and the agent verifies it exactly as a mailbox message.
|
|
247
|
+
`--mailbox-only` ignores it.
|
|
248
|
+
- **Grant requests** travel as a link: 276 characters with a 16-byte
|
|
249
|
+
`client_id`, up to about 600 with the longest the form admits
|
|
250
|
+
(`midnight-mandate:grant-request?r=…`), which `scripts/agentRequest.ts`
|
|
251
|
+
prints and `cli/owner.ts issue` takes.
|
|
252
|
+
|
|
253
|
+
On chain:
|
|
254
|
+
- **Learned from chain alone.** An agent ignoring every file learned a new
|
|
255
|
+
grant from the mailbox and paid under it.
|
|
256
|
+
- **Re-seals arrive.** An older grant's re-seal arrived through the mailbox.
|
|
257
|
+
- **Other readers.** The owner's coin walk skipped every mailbox entry.
|
|
258
|
+
- **Cost.** Each message is two appends, about 48 s together here.
|
|
259
|
+
|
|
260
|
+
### On chain, beyond the first grant
|
|
261
|
+
|
|
262
|
+
Every one of these was run against the node:
|
|
263
|
+
- **Both owner-device arms.** A k1-born account activates, withdraws and
|
|
264
|
+
backfills with `_with_k256` circuits, then issues a grant with
|
|
265
|
+
`issue_grant_with_k256`.
|
|
266
|
+
- **Both grantee arms.** A secp256k1 grantee under envelope 0 pays with
|
|
267
|
+
`withdraw_shielded_with_grant_k256`. Envelope-1 grantees are read-only, by
|
|
268
|
+
the draft's section 3.2.
|
|
269
|
+
- **Paying a contract.** The owner's `withdraw_shielded_to_contract_with_jubjub`
|
|
270
|
+
and an agent's `withdraw_shielded_to_contract_with_grant_jubjub` each land
|
|
271
|
+
in one transaction with the payee's `deposit_shielded` claim
|
|
272
|
+
(`src/compose.ts`), and the payee's own walk finds the coin.
|
|
273
|
+
- **In flight.** A spend proved before a deposit, or before a revocation, is
|
|
274
|
+
refused from the mempool on the read that changed: `round`, or the
|
|
275
|
+
record's `active`.
|
|
276
|
+
- **Revocation.** `revoke_grant` and `revoke_all_grants`, each followed by
|
|
277
|
+
the rotation. Afterwards the revoked agent's view still opens, to a secret
|
|
278
|
+
that is no longer `enc_key`, so the agent refuses to act on it ("reconnect
|
|
279
|
+
to the owner"). After revoke-all, its record is gone as well.
|
|
280
|
+
|
|
281
|
+
### Findings
|
|
282
|
+
|
|
283
|
+
The findings written up for their teams are in `../docs/findings/`.
|
|
284
|
+
|
|
285
|
+
- **An unshielded deposit is refused by the fee computation.**
|
|
286
|
+
`deposit_unshielded` fails with custom error 231,
|
|
287
|
+
`FeeCalculationError::OutsideTimeToDismiss`. Under the on-chain ledger
|
|
288
|
+
parameters (read from the indexer's `block.ledgerParameters`), validation
|
|
289
|
+
plus guaranteed cost comes out 21 µs over the time-to-dismiss bound.
|
|
290
|
+
`scripts/diagnoseDeposit.ts` reproduces it. The shielded path runs instead.
|
|
291
|
+
- **The change coin is predictable, as the draft says.** A grantee seals the
|
|
292
|
+
change entry, which the challenge covers, before the proof exists. The
|
|
293
|
+
draft's section 6.5 gives the change nonce as Compact's stdlib evolution of
|
|
294
|
+
the spent nonce under `midnight:kernel:nonce_evolve/2`. It matched every
|
|
295
|
+
change the chain created here (`chain/src/coins.ts`, `changeCoinOf`).
|
|
296
|
+
- **Paying a pinned shielded recipient needs its encryption key.** The grant
|
|
297
|
+
pins the merchant by coin public key (`recipient_kind` 2). midnight-js still
|
|
298
|
+
refuses to build the output without the recipient's encryption public key:
|
|
299
|
+
it encrypts the output so the recipient's wallet finds the coin. So the
|
|
300
|
+
grantee needs the merchant's full shielded address, off chain. Neither the
|
|
301
|
+
grant nor the request carries it.
|