viz-js-lib 0.11.0 → 0.12.4
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/.qoder/docs/spec/viz-dns-nameserver-spec.md +982 -0
- package/.qoder/docs/viz-cpp-node-docs/data-types.md +322 -0
- package/.qoder/docs/viz-cpp-node-docs/index.md +160 -0
- package/.qoder/docs/viz-cpp-node-docs/op-account-market.md +236 -0
- package/.qoder/docs/viz-cpp-node-docs/op-account.md +199 -0
- package/.qoder/docs/viz-cpp-node-docs/op-award.md +162 -0
- package/.qoder/docs/viz-cpp-node-docs/op-committee.md +193 -0
- package/.qoder/docs/viz-cpp-node-docs/op-content.md +157 -0
- package/.qoder/docs/viz-cpp-node-docs/op-escrow.md +224 -0
- package/.qoder/docs/viz-cpp-node-docs/op-invite.md +219 -0
- package/.qoder/docs/viz-cpp-node-docs/op-proposal.md +229 -0
- package/.qoder/docs/viz-cpp-node-docs/op-recovery.md +188 -0
- package/.qoder/docs/viz-cpp-node-docs/op-subscription.md +146 -0
- package/.qoder/docs/viz-cpp-node-docs/op-transfer-vesting.md +224 -0
- package/.qoder/docs/viz-cpp-node-docs/op-witness.md +252 -0
- package/.qoder/docs/viz-cpp-node-docs/plugins.md +887 -0
- package/.qoder/docs/viz-cpp-node-docs/virtual-operations.md +513 -0
- package/.qoder/repowiki/en/content/API Reference/API Reference.md +724 -0
- package/.qoder/repowiki/en/content/API Reference/Configuration Options.md +410 -0
- package/.qoder/repowiki/en/content/API Reference/Core API Methods.md +547 -0
- package/.qoder/repowiki/en/content/API Reference/Streaming APIs.md +380 -0
- package/.qoder/repowiki/en/content/API Reference/Transport Layer.md +341 -0
- package/.qoder/repowiki/en/content/API Reference/VIZ Blockchain Operations Coverage Status.md +427 -0
- package/.qoder/repowiki/en/content/Authentication & Cryptography/Authentication & Cryptography.md +430 -0
- package/.qoder/repowiki/en/content/Authentication & Cryptography/Digital Signatures.md +462 -0
- package/.qoder/repowiki/en/content/Authentication & Cryptography/Key Management.md +456 -0
- package/.qoder/repowiki/en/content/Authentication & Cryptography/Memo Encryption.md +331 -0
- package/.qoder/repowiki/en/content/Authentication & Cryptography/Security Practices.md +488 -0
- package/.qoder/repowiki/en/content/Broadcast Transactions/Broadcast Transactions.md +432 -0
- package/.qoder/repowiki/en/content/Broadcast Transactions/Network Broadcasting.md +418 -0
- package/.qoder/repowiki/en/content/Broadcast Transactions/Operation Construction.md +352 -0
- package/.qoder/repowiki/en/content/Broadcast Transactions/Transaction Preparation.md +353 -0
- package/.qoder/repowiki/en/content/Broadcast Transactions/Transaction Signing.md +404 -0
- package/.qoder/repowiki/en/content/Data Serialization/Data Serialization.md +540 -0
- package/.qoder/repowiki/en/content/Data Serialization/Encoding & Decoding.md +463 -0
- package/.qoder/repowiki/en/content/Data Serialization/Object Templates.md +413 -0
- package/.qoder/repowiki/en/content/Data Serialization/Type System.md +514 -0
- package/.qoder/repowiki/en/content/Data Serialization/Validation Rules.md +439 -0
- package/.qoder/repowiki/en/content/Examples & Tutorials.md +485 -0
- package/.qoder/repowiki/en/content/Getting Started.md +345 -0
- package/.qoder/repowiki/en/content/Testing & Development.md +637 -0
- package/.qoder/repowiki/en/content/Utilities & Helpers.md +557 -0
- package/.qoder/repowiki/en/meta/repowiki-metadata.json +1 -0
- package/VIZ-JS-LIB-COVERAGE-STATUS.md +356 -0
- package/config.json +3 -1
- package/dist/statistics.html +1 -1
- package/dist/viz-tests.min.js +32 -42
- package/dist/viz-tests.min.js.gz +0 -0
- package/dist/viz.min.js +8 -18
- package/dist/viz.min.js.gz +0 -0
- package/lib/api/methods.js +24 -0
- package/lib/auth/serializer/src/ChainTypes.js +2 -1
- package/lib/auth/serializer/src/operations.js +35 -2
- package/lib/broadcast/index.js +29 -15
- package/lib/broadcast/operations.js +4 -0
- package/lib/dns.js +658 -0
- package/lib/index.js +3 -1
- package/package.json +3 -2
- package/test/dns.test.js +395 -0
- package/webpack/makeConfig.js +3 -0
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
# VIZ Blockchain — Invite Operations
|
|
2
|
+
|
|
3
|
+
Spec for implementing invite-related operations in PHP/Node.js libraries.
|
|
4
|
+
|
|
5
|
+
Invites allow existing VIZ users to onboard new users without requiring them to have an existing account. An invite is a one-time-use key with a VIZ balance.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## `create_invite_operation`
|
|
10
|
+
|
|
11
|
+
**Type ID:** `43`
|
|
12
|
+
**Required authority:** `active` of `creator`
|
|
13
|
+
|
|
14
|
+
Creates an invite link by generating a key and funding it with VIZ tokens.
|
|
15
|
+
|
|
16
|
+
### Fields
|
|
17
|
+
|
|
18
|
+
| Field | Type | Required | Description |
|
|
19
|
+
|---|---|---|---|
|
|
20
|
+
| `creator` | `account_name_type` | yes | Account creating the invite |
|
|
21
|
+
| `balance` | `asset` (VIZ) | yes | Amount of VIZ to lock in the invite |
|
|
22
|
+
| `invite_key` | `public_key_type` | yes | Public key of the invite (secret = private key) |
|
|
23
|
+
|
|
24
|
+
### JSON Example
|
|
25
|
+
|
|
26
|
+
```json
|
|
27
|
+
[43, {
|
|
28
|
+
"creator": "alice",
|
|
29
|
+
"balance": "5.000 VIZ",
|
|
30
|
+
"invite_key": "VIZ5invite..."
|
|
31
|
+
}]
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### PHP Example
|
|
35
|
+
|
|
36
|
+
```php
|
|
37
|
+
// Generate invite key pair first:
|
|
38
|
+
// $privateKey = '...' // keep secret, share as invite link
|
|
39
|
+
// $publicKey = derived from privateKey
|
|
40
|
+
|
|
41
|
+
$op = [
|
|
42
|
+
'type' => 'create_invite_operation',
|
|
43
|
+
'value' => [
|
|
44
|
+
'creator' => 'alice',
|
|
45
|
+
'balance' => '5.000 VIZ',
|
|
46
|
+
'invite_key' => 'VIZ5invite...',
|
|
47
|
+
],
|
|
48
|
+
];
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### Node.js Example
|
|
52
|
+
|
|
53
|
+
```js
|
|
54
|
+
const op = ['create_invite', {
|
|
55
|
+
creator: 'alice',
|
|
56
|
+
balance: '5.000 VIZ',
|
|
57
|
+
invite_key: 'VIZ5invite...',
|
|
58
|
+
}];
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### Checklist
|
|
62
|
+
- [ ] `balance.symbol` must be `VIZ`
|
|
63
|
+
- [ ] `balance.amount` >= chain `create_invite_min_balance` property
|
|
64
|
+
- [ ] Generate a random secp256k1 key pair for the invite
|
|
65
|
+
- [ ] Private key = invite secret (share in invite link)
|
|
66
|
+
- [ ] Public key = `invite_key` field
|
|
67
|
+
- [ ] Sign with `creator`'s active key
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
## `claim_invite_balance_operation`
|
|
72
|
+
|
|
73
|
+
**Type ID:** `44`
|
|
74
|
+
**Required authority:** `active` of `initiator`
|
|
75
|
+
|
|
76
|
+
Claims the VIZ balance from an invite, transferring it to `receiver`. The invite is consumed.
|
|
77
|
+
|
|
78
|
+
### Fields
|
|
79
|
+
|
|
80
|
+
| Field | Type | Required | Description |
|
|
81
|
+
|---|---|---|---|
|
|
82
|
+
| `initiator` | `account_name_type` | yes | Account claiming the invite |
|
|
83
|
+
| `receiver` | `account_name_type` | yes | Account to receive the VIZ balance |
|
|
84
|
+
| `invite_secret` | `string` | yes | WIF private key of the invite |
|
|
85
|
+
|
|
86
|
+
### JSON Example
|
|
87
|
+
|
|
88
|
+
```json
|
|
89
|
+
[44, {
|
|
90
|
+
"initiator": "bob",
|
|
91
|
+
"receiver": "bob",
|
|
92
|
+
"invite_secret": "5Ky1MXn..."
|
|
93
|
+
}]
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### PHP Example
|
|
97
|
+
|
|
98
|
+
```php
|
|
99
|
+
$op = [
|
|
100
|
+
'type' => 'claim_invite_balance_operation',
|
|
101
|
+
'value' => [
|
|
102
|
+
'initiator' => 'bob',
|
|
103
|
+
'receiver' => 'bob',
|
|
104
|
+
'invite_secret' => '5Ky1MXn...',
|
|
105
|
+
],
|
|
106
|
+
];
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### Node.js Example
|
|
110
|
+
|
|
111
|
+
```js
|
|
112
|
+
const op = ['claim_invite_balance', {
|
|
113
|
+
initiator: 'bob',
|
|
114
|
+
receiver: 'bob',
|
|
115
|
+
invite_secret: '5Ky1MXn...',
|
|
116
|
+
}];
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
### Checklist
|
|
120
|
+
- [ ] `invite_secret` is the WIF (Wallet Import Format) private key of the invite
|
|
121
|
+
- [ ] `initiator` must be an existing account
|
|
122
|
+
- [ ] `receiver` may differ from `initiator` (can redirect balance to another account)
|
|
123
|
+
- [ ] Invite is consumed after claiming — cannot be reused
|
|
124
|
+
- [ ] Sign with `initiator`'s active key
|
|
125
|
+
|
|
126
|
+
---
|
|
127
|
+
|
|
128
|
+
## `invite_registration_operation`
|
|
129
|
+
|
|
130
|
+
**Type ID:** `45`
|
|
131
|
+
**Required authority:** `active` of `initiator`
|
|
132
|
+
|
|
133
|
+
Uses an invite to create a new account. The invite balance is used to fund the new account.
|
|
134
|
+
|
|
135
|
+
### Fields
|
|
136
|
+
|
|
137
|
+
| Field | Type | Required | Description |
|
|
138
|
+
|---|---|---|---|
|
|
139
|
+
| `initiator` | `account_name_type` | yes | Existing account triggering registration |
|
|
140
|
+
| `new_account_name` | `account_name_type` | yes | Name for the new account |
|
|
141
|
+
| `invite_secret` | `string` | yes | WIF private key of the invite |
|
|
142
|
+
| `new_account_key` | `public_key_type` | yes | Master/active/regular/memo key for new account |
|
|
143
|
+
|
|
144
|
+
### JSON Example
|
|
145
|
+
|
|
146
|
+
```json
|
|
147
|
+
[45, {
|
|
148
|
+
"initiator": "bob",
|
|
149
|
+
"new_account_name": "carol",
|
|
150
|
+
"invite_secret": "5Ky1MXn...",
|
|
151
|
+
"new_account_key": "VIZ5newacct..."
|
|
152
|
+
}]
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
### PHP Example
|
|
156
|
+
|
|
157
|
+
```php
|
|
158
|
+
$op = [
|
|
159
|
+
'type' => 'invite_registration_operation',
|
|
160
|
+
'value' => [
|
|
161
|
+
'initiator' => 'bob',
|
|
162
|
+
'new_account_name' => 'carol',
|
|
163
|
+
'invite_secret' => '5Ky1MXn...',
|
|
164
|
+
'new_account_key' => 'VIZ5newacct...',
|
|
165
|
+
],
|
|
166
|
+
];
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
### Node.js Example
|
|
170
|
+
|
|
171
|
+
```js
|
|
172
|
+
const op = ['invite_registration', {
|
|
173
|
+
initiator: 'bob',
|
|
174
|
+
new_account_name: 'carol',
|
|
175
|
+
invite_secret: '5Ky1MXn...',
|
|
176
|
+
new_account_key: 'VIZ5newacct...',
|
|
177
|
+
}];
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
### Checklist
|
|
181
|
+
- [ ] `invite_secret` is the WIF private key of the invite
|
|
182
|
+
- [ ] `new_account_name` must pass account name validation
|
|
183
|
+
- [ ] `new_account_key` is set as all four keys (master, active, regular, memo) for the new account
|
|
184
|
+
- [ ] Invite balance is converted to SHARES for the new account
|
|
185
|
+
- [ ] Invite is consumed after use
|
|
186
|
+
- [ ] Sign with `initiator`'s active key
|
|
187
|
+
|
|
188
|
+
---
|
|
189
|
+
|
|
190
|
+
## `use_invite_balance_operation`
|
|
191
|
+
|
|
192
|
+
**Type ID:** `58`
|
|
193
|
+
**Required authority:** `active` of `initiator`
|
|
194
|
+
|
|
195
|
+
Alternative to `claim_invite_balance_operation` — transfers invite balance to receiver. The difference from `claim_invite_balance_operation` is that this one may convert balance to SHARES.
|
|
196
|
+
|
|
197
|
+
### Fields
|
|
198
|
+
|
|
199
|
+
| Field | Type | Required | Description |
|
|
200
|
+
|---|---|---|---|
|
|
201
|
+
| `initiator` | `account_name_type` | yes | Account using the invite |
|
|
202
|
+
| `receiver` | `account_name_type` | yes | Account receiving the balance |
|
|
203
|
+
| `invite_secret` | `string` | yes | WIF private key of the invite |
|
|
204
|
+
|
|
205
|
+
### JSON Example
|
|
206
|
+
|
|
207
|
+
```json
|
|
208
|
+
[58, {
|
|
209
|
+
"initiator": "bob",
|
|
210
|
+
"receiver": "bob",
|
|
211
|
+
"invite_secret": "5Ky1MXn..."
|
|
212
|
+
}]
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
### Checklist
|
|
216
|
+
- [ ] `invite_secret` is the WIF private key
|
|
217
|
+
- [ ] `receiver` must be an existing account
|
|
218
|
+
- [ ] Invite is consumed after use
|
|
219
|
+
- [ ] Sign with `initiator`'s active key
|
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
# VIZ Blockchain — Proposal Operations
|
|
2
|
+
|
|
3
|
+
Spec for implementing multi-signature proposal operations in PHP/Node.js libraries.
|
|
4
|
+
|
|
5
|
+
Proposals allow a group of accounts to jointly approve and execute a set of operations. Any account can create a proposal; signatories approve via `proposal_update_operation`.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## `proposal_create_operation`
|
|
10
|
+
|
|
11
|
+
**Type ID:** `22`
|
|
12
|
+
**Required authority:** `active` of `author`
|
|
13
|
+
|
|
14
|
+
Creates a transaction proposal containing one or more operations that require multi-sig approval.
|
|
15
|
+
|
|
16
|
+
### Fields
|
|
17
|
+
|
|
18
|
+
| Field | Type | Required | Description |
|
|
19
|
+
|---|---|---|---|
|
|
20
|
+
| `author` | `account_name_type` | yes | Account creating the proposal |
|
|
21
|
+
| `title` | `string` | yes | Unique title per author (used as proposal ID) |
|
|
22
|
+
| `memo` | `string` | yes | Description of the proposal |
|
|
23
|
+
| `expiration_time` | `time_point_sec` | yes | Proposal expiration time |
|
|
24
|
+
| `proposed_operations` | `vector<operation_wrapper>` | yes | Operations in the proposal |
|
|
25
|
+
| `review_period_time` | `optional<time_point_sec>` | no | Optional review period |
|
|
26
|
+
| `extensions` | `extensions_type` | yes | Always `[]` |
|
|
27
|
+
|
|
28
|
+
### `operation_wrapper`
|
|
29
|
+
|
|
30
|
+
Each entry in `proposed_operations` is an `operation_wrapper`:
|
|
31
|
+
```json
|
|
32
|
+
{"op": [type_id, operation_object]}
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### JSON Example
|
|
36
|
+
|
|
37
|
+
```json
|
|
38
|
+
[22, {
|
|
39
|
+
"author": "alice",
|
|
40
|
+
"title": "transfer-proposal-001",
|
|
41
|
+
"memo": "Joint transfer to shared fund",
|
|
42
|
+
"expiration_time": "2024-12-31T23:59:59",
|
|
43
|
+
"proposed_operations": [
|
|
44
|
+
{
|
|
45
|
+
"op": [2, {
|
|
46
|
+
"from": "multisig-wallet",
|
|
47
|
+
"to": "fund",
|
|
48
|
+
"amount": "1000.000 VIZ",
|
|
49
|
+
"memo": ""
|
|
50
|
+
}]
|
|
51
|
+
}
|
|
52
|
+
],
|
|
53
|
+
"review_period_time": null,
|
|
54
|
+
"extensions": []
|
|
55
|
+
}]
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### PHP Example
|
|
59
|
+
|
|
60
|
+
```php
|
|
61
|
+
$op = [
|
|
62
|
+
'type' => 'proposal_create_operation',
|
|
63
|
+
'value' => [
|
|
64
|
+
'author' => 'alice',
|
|
65
|
+
'title' => 'transfer-proposal-001',
|
|
66
|
+
'memo' => 'Joint transfer to shared fund',
|
|
67
|
+
'expiration_time' => '2024-12-31T23:59:59',
|
|
68
|
+
'proposed_operations' => [
|
|
69
|
+
['op' => [2, [
|
|
70
|
+
'from' => 'multisig-wallet',
|
|
71
|
+
'to' => 'fund',
|
|
72
|
+
'amount' => '1000.000 VIZ',
|
|
73
|
+
'memo' => '',
|
|
74
|
+
]]],
|
|
75
|
+
],
|
|
76
|
+
'review_period_time' => null,
|
|
77
|
+
'extensions' => [],
|
|
78
|
+
],
|
|
79
|
+
];
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### Node.js Example
|
|
83
|
+
|
|
84
|
+
```js
|
|
85
|
+
const op = ['proposal_create', {
|
|
86
|
+
author: 'alice',
|
|
87
|
+
title: 'transfer-proposal-001',
|
|
88
|
+
memo: 'Joint transfer to shared fund',
|
|
89
|
+
expiration_time: '2024-12-31T23:59:59',
|
|
90
|
+
proposed_operations: [
|
|
91
|
+
{ op: ['transfer', {
|
|
92
|
+
from: 'multisig-wallet',
|
|
93
|
+
to: 'fund',
|
|
94
|
+
amount: '1000.000 VIZ',
|
|
95
|
+
memo: '',
|
|
96
|
+
}] },
|
|
97
|
+
],
|
|
98
|
+
review_period_time: null,
|
|
99
|
+
extensions: [],
|
|
100
|
+
}];
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### Checklist
|
|
104
|
+
- [ ] `title` must be unique per `author` (together they form the proposal ID)
|
|
105
|
+
- [ ] `expiration_time` must be in the future
|
|
106
|
+
- [ ] `review_period_time` if set, must be before `expiration_time`
|
|
107
|
+
- [ ] `proposed_operations` may contain multiple operations
|
|
108
|
+
- [ ] Operations inside a proposal follow the same rules as normal operations
|
|
109
|
+
- [ ] Sign with `author`'s active key
|
|
110
|
+
|
|
111
|
+
---
|
|
112
|
+
|
|
113
|
+
## `proposal_update_operation`
|
|
114
|
+
|
|
115
|
+
**Type ID:** `23`
|
|
116
|
+
**Required authority:** Depends on which approval sets are modified
|
|
117
|
+
|
|
118
|
+
Adds or removes approvals from a proposal. Proposal executes automatically when enough approvals are collected.
|
|
119
|
+
|
|
120
|
+
### Fields
|
|
121
|
+
|
|
122
|
+
| Field | Type | Required | Description |
|
|
123
|
+
|---|---|---|---|
|
|
124
|
+
| `author` | `account_name_type` | yes | Author of the proposal |
|
|
125
|
+
| `title` | `string` | yes | Title of the proposal |
|
|
126
|
+
| `active_approvals_to_add` | `flat_set<account_name_type>` | yes | Accounts adding active approval |
|
|
127
|
+
| `active_approvals_to_remove` | `flat_set<account_name_type>` | yes | Accounts removing active approval |
|
|
128
|
+
| `master_approvals_to_add` | `flat_set<account_name_type>` | yes | Accounts adding master approval |
|
|
129
|
+
| `master_approvals_to_remove` | `flat_set<account_name_type>` | yes | Accounts removing master approval |
|
|
130
|
+
| `regular_approvals_to_add` | `flat_set<account_name_type>` | yes | Accounts adding regular approval |
|
|
131
|
+
| `regular_approvals_to_remove` | `flat_set<account_name_type>` | yes | Accounts removing regular approval |
|
|
132
|
+
| `key_approvals_to_add` | `flat_set<public_key_type>` | yes | Keys adding approval |
|
|
133
|
+
| `key_approvals_to_remove` | `flat_set<public_key_type>` | yes | Keys removing approval |
|
|
134
|
+
| `extensions` | `extensions_type` | yes | Always `[]` |
|
|
135
|
+
|
|
136
|
+
### JSON Example
|
|
137
|
+
|
|
138
|
+
```json
|
|
139
|
+
[23, {
|
|
140
|
+
"author": "alice",
|
|
141
|
+
"title": "transfer-proposal-001",
|
|
142
|
+
"active_approvals_to_add": ["bob"],
|
|
143
|
+
"active_approvals_to_remove": [],
|
|
144
|
+
"master_approvals_to_add": [],
|
|
145
|
+
"master_approvals_to_remove": [],
|
|
146
|
+
"regular_approvals_to_add": [],
|
|
147
|
+
"regular_approvals_to_remove": [],
|
|
148
|
+
"key_approvals_to_add": [],
|
|
149
|
+
"key_approvals_to_remove": [],
|
|
150
|
+
"extensions": []
|
|
151
|
+
}]
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
### PHP Example
|
|
155
|
+
|
|
156
|
+
```php
|
|
157
|
+
$op = [
|
|
158
|
+
'type' => 'proposal_update_operation',
|
|
159
|
+
'value' => [
|
|
160
|
+
'author' => 'alice',
|
|
161
|
+
'title' => 'transfer-proposal-001',
|
|
162
|
+
'active_approvals_to_add' => ['bob'],
|
|
163
|
+
'active_approvals_to_remove'=> [],
|
|
164
|
+
'master_approvals_to_add' => [],
|
|
165
|
+
'master_approvals_to_remove'=> [],
|
|
166
|
+
'regular_approvals_to_add' => [],
|
|
167
|
+
'regular_approvals_to_remove'=> [],
|
|
168
|
+
'key_approvals_to_add' => [],
|
|
169
|
+
'key_approvals_to_remove' => [],
|
|
170
|
+
'extensions' => [],
|
|
171
|
+
],
|
|
172
|
+
];
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
### Checklist
|
|
176
|
+
- [ ] Transaction must be signed by keys satisfying the authorities being added/removed
|
|
177
|
+
- [ ] If proposal requires only active authority, do NOT add master authority
|
|
178
|
+
- [ ] If both master and active are required, only master can approve
|
|
179
|
+
- [ ] Proposal executes automatically when approval threshold is reached
|
|
180
|
+
- [ ] After successful execution, proposal is resolved and further updates are rejected
|
|
181
|
+
- [ ] All `*_to_add` and `*_to_remove` arrays default to `[]` if not needed
|
|
182
|
+
|
|
183
|
+
---
|
|
184
|
+
|
|
185
|
+
## `proposal_delete_operation`
|
|
186
|
+
|
|
187
|
+
**Type ID:** `24`
|
|
188
|
+
**Required authority:** `active` of `requester`
|
|
189
|
+
|
|
190
|
+
Vetoes and permanently deletes a proposal. Can be done by any required authority.
|
|
191
|
+
|
|
192
|
+
### Fields
|
|
193
|
+
|
|
194
|
+
| Field | Type | Required | Description |
|
|
195
|
+
|---|---|---|---|
|
|
196
|
+
| `author` | `account_name_type` | yes | Author of the proposal |
|
|
197
|
+
| `title` | `string` | yes | Title of the proposal |
|
|
198
|
+
| `requester` | `account_name_type` | yes | Account requesting deletion |
|
|
199
|
+
| `extensions` | `extensions_type` | yes | Always `[]` |
|
|
200
|
+
|
|
201
|
+
### JSON Example
|
|
202
|
+
|
|
203
|
+
```json
|
|
204
|
+
[24, {
|
|
205
|
+
"author": "alice",
|
|
206
|
+
"title": "transfer-proposal-001",
|
|
207
|
+
"requester": "bob",
|
|
208
|
+
"extensions": []
|
|
209
|
+
}]
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
### PHP Example
|
|
213
|
+
|
|
214
|
+
```php
|
|
215
|
+
$op = [
|
|
216
|
+
'type' => 'proposal_delete_operation',
|
|
217
|
+
'value' => [
|
|
218
|
+
'author' => 'alice',
|
|
219
|
+
'title' => 'transfer-proposal-001',
|
|
220
|
+
'requester' => 'bob',
|
|
221
|
+
'extensions' => [],
|
|
222
|
+
],
|
|
223
|
+
];
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
### Checklist
|
|
227
|
+
- [ ] `requester` must be a required authority on the proposal
|
|
228
|
+
- [ ] Permanently removes the proposal — cannot be undone
|
|
229
|
+
- [ ] Sign with `requester`'s active key
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
# VIZ Blockchain — Account Recovery Operations
|
|
2
|
+
|
|
3
|
+
Spec for implementing account recovery operations in PHP/Node.js libraries.
|
|
4
|
+
|
|
5
|
+
The recovery mechanism allows a trusted recovery account to help restore access to a compromised account using a previous valid master authority.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Recovery Flow
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
request_account_recovery → recover_account (within 24 hours)
|
|
13
|
+
change_recovery_account (30-day delay)
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## `request_account_recovery_operation`
|
|
19
|
+
|
|
20
|
+
**Type ID:** `12`
|
|
21
|
+
**Required authority:** `active` of `recovery_account`
|
|
22
|
+
|
|
23
|
+
Initiates an account recovery request. The recovery account proposes a new master authority for the compromised account. The account holder has 24 hours to confirm.
|
|
24
|
+
|
|
25
|
+
### Fields
|
|
26
|
+
|
|
27
|
+
| Field | Type | Required | Description |
|
|
28
|
+
|---|---|---|---|
|
|
29
|
+
| `recovery_account` | `account_name_type` | yes | The trusted recovery account |
|
|
30
|
+
| `account_to_recover` | `account_name_type` | yes | Compromised account to recover |
|
|
31
|
+
| `new_master_authority` | `authority` | yes | The new master authority to assign |
|
|
32
|
+
| `extensions` | `extensions_type` | yes | Always `[]` |
|
|
33
|
+
|
|
34
|
+
### JSON Example
|
|
35
|
+
|
|
36
|
+
```json
|
|
37
|
+
[12, {
|
|
38
|
+
"recovery_account": "recover-service",
|
|
39
|
+
"account_to_recover": "alice",
|
|
40
|
+
"new_master_authority": {
|
|
41
|
+
"weight_threshold": 1,
|
|
42
|
+
"account_auths": [],
|
|
43
|
+
"key_auths": [["VIZ5newkey...", 1]]
|
|
44
|
+
},
|
|
45
|
+
"extensions": []
|
|
46
|
+
}]
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### PHP Example
|
|
50
|
+
|
|
51
|
+
```php
|
|
52
|
+
$op = [
|
|
53
|
+
'type' => 'request_account_recovery_operation',
|
|
54
|
+
'value' => [
|
|
55
|
+
'recovery_account' => 'recover-service',
|
|
56
|
+
'account_to_recover' => 'alice',
|
|
57
|
+
'new_master_authority' => [
|
|
58
|
+
'weight_threshold' => 1,
|
|
59
|
+
'account_auths' => [],
|
|
60
|
+
'key_auths' => [['VIZ5newkey...', 1]],
|
|
61
|
+
],
|
|
62
|
+
'extensions' => [],
|
|
63
|
+
],
|
|
64
|
+
];
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### Node.js Example
|
|
68
|
+
|
|
69
|
+
```js
|
|
70
|
+
const op = ['request_account_recovery', {
|
|
71
|
+
recovery_account: 'recover-service',
|
|
72
|
+
account_to_recover: 'alice',
|
|
73
|
+
new_master_authority: {
|
|
74
|
+
weight_threshold: 1,
|
|
75
|
+
account_auths: [],
|
|
76
|
+
key_auths: [['VIZ5newkey...', 1]],
|
|
77
|
+
},
|
|
78
|
+
extensions: [],
|
|
79
|
+
}];
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### Checklist
|
|
83
|
+
- [ ] Only the listed recovery account of `account_to_recover` can send this
|
|
84
|
+
- [ ] Only one active recovery request per account at any time
|
|
85
|
+
- [ ] Sending again updates the request to a new authority and resets the 24h timer
|
|
86
|
+
- [ ] To cancel: set `new_master_authority.weight_threshold` to `0`
|
|
87
|
+
- [ ] Sign with `recovery_account`'s active key
|
|
88
|
+
|
|
89
|
+
---
|
|
90
|
+
|
|
91
|
+
## `recover_account_operation`
|
|
92
|
+
|
|
93
|
+
**Type ID:** `13`
|
|
94
|
+
**Required authority:** Both `new_master_authority` AND `recent_master_authority` signatures
|
|
95
|
+
|
|
96
|
+
Confirms account recovery. The account holder proves past ownership via a recent master authority, and takes the new master authority.
|
|
97
|
+
|
|
98
|
+
### Fields
|
|
99
|
+
|
|
100
|
+
| Field | Type | Required | Description |
|
|
101
|
+
|---|---|---|---|
|
|
102
|
+
| `account_to_recover` | `account_name_type` | yes | Account being recovered |
|
|
103
|
+
| `new_master_authority` | `authority` | yes | New master authority (must match recovery request) |
|
|
104
|
+
| `recent_master_authority` | `authority` | yes | A previous valid master authority (within last 30 days) |
|
|
105
|
+
| `extensions` | `extensions_type` | yes | Always `[]` |
|
|
106
|
+
|
|
107
|
+
### JSON Example
|
|
108
|
+
|
|
109
|
+
```json
|
|
110
|
+
[13, {
|
|
111
|
+
"account_to_recover": "alice",
|
|
112
|
+
"new_master_authority": {
|
|
113
|
+
"weight_threshold": 1,
|
|
114
|
+
"account_auths": [],
|
|
115
|
+
"key_auths": [["VIZ5newkey...", 1]]
|
|
116
|
+
},
|
|
117
|
+
"recent_master_authority": {
|
|
118
|
+
"weight_threshold": 1,
|
|
119
|
+
"account_auths": [],
|
|
120
|
+
"key_auths": [["VIZ5oldkey...", 1]]
|
|
121
|
+
},
|
|
122
|
+
"extensions": []
|
|
123
|
+
}]
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
### Checklist
|
|
127
|
+
- [ ] Must be broadcast within 24 hours of the recovery request
|
|
128
|
+
- [ ] `new_master_authority` must exactly match the one in the recovery request
|
|
129
|
+
- [ ] `recent_master_authority` must have been valid in the past 30 days
|
|
130
|
+
- [ ] Transaction must be signed by keys satisfying **both** authorities
|
|
131
|
+
- [ ] After recovery, the old master key is invalidated
|
|
132
|
+
|
|
133
|
+
---
|
|
134
|
+
|
|
135
|
+
## `change_recovery_account_operation`
|
|
136
|
+
|
|
137
|
+
**Type ID:** `14`
|
|
138
|
+
**Required authority:** `master` of `account_to_recover`
|
|
139
|
+
|
|
140
|
+
Changes the recovery account for an account. Takes effect after a 30-day delay.
|
|
141
|
+
|
|
142
|
+
### Fields
|
|
143
|
+
|
|
144
|
+
| Field | Type | Required | Description |
|
|
145
|
+
|---|---|---|---|
|
|
146
|
+
| `account_to_recover` | `account_name_type` | yes | Account changing its recovery account |
|
|
147
|
+
| `new_recovery_account` | `account_name_type` | yes | New recovery account name |
|
|
148
|
+
| `extensions` | `extensions_type` | yes | Always `[]` |
|
|
149
|
+
|
|
150
|
+
### JSON Example
|
|
151
|
+
|
|
152
|
+
```json
|
|
153
|
+
[14, {
|
|
154
|
+
"account_to_recover": "alice",
|
|
155
|
+
"new_recovery_account": "new-recovery-service",
|
|
156
|
+
"extensions": []
|
|
157
|
+
}]
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
### PHP Example
|
|
161
|
+
|
|
162
|
+
```php
|
|
163
|
+
$op = [
|
|
164
|
+
'type' => 'change_recovery_account_operation',
|
|
165
|
+
'value' => [
|
|
166
|
+
'account_to_recover' => 'alice',
|
|
167
|
+
'new_recovery_account' => 'new-recovery-service',
|
|
168
|
+
'extensions' => [],
|
|
169
|
+
],
|
|
170
|
+
];
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
### Node.js Example
|
|
174
|
+
|
|
175
|
+
```js
|
|
176
|
+
const op = ['change_recovery_account', {
|
|
177
|
+
account_to_recover: 'alice',
|
|
178
|
+
new_recovery_account: 'new-recovery-service',
|
|
179
|
+
extensions: [],
|
|
180
|
+
}];
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
### Checklist
|
|
184
|
+
- [ ] 30-day delay between submitting the change and it taking effect
|
|
185
|
+
- [ ] This prevents attackers from changing the recovery account during an active attack
|
|
186
|
+
- [ ] `new_recovery_account` must be an existing account
|
|
187
|
+
- [ ] If `new_recovery_account == ""`, top-voted witness becomes recovery account
|
|
188
|
+
- [ ] Sign with `account_to_recover`'s master key
|