bitbadgesjs-sdk 0.31.0 → 0.31.2
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/dist/cjs/api-indexer/BitBadgesCollection.d.ts +1 -0
- package/dist/cjs/api-indexer/BitBadgesCollection.d.ts.map +1 -1
- package/dist/cjs/api-indexer/BitBadgesCollection.js +4 -1
- package/dist/cjs/api-indexer/BitBadgesCollection.js.map +1 -1
- package/dist/cjs/core/approval-utils.spec.d.ts +2 -0
- package/dist/cjs/core/approval-utils.spec.d.ts.map +1 -0
- package/dist/cjs/core/approval-utils.spec.js +240 -0
- package/dist/cjs/core/approval-utils.spec.js.map +1 -0
- package/dist/cjs/core/approvals.spec.js +96 -0
- package/dist/cjs/core/approvals.spec.js.map +1 -1
- package/dist/cjs/core/bids.spec.d.ts +2 -0
- package/dist/cjs/core/bids.spec.d.ts.map +1 -0
- package/dist/cjs/core/bids.spec.js +201 -0
- package/dist/cjs/core/bids.spec.js.map +1 -0
- package/dist/cjs/core/blockin.spec.d.ts +2 -0
- package/dist/cjs/core/blockin.spec.d.ts.map +1 -0
- package/dist/cjs/core/blockin.spec.js +163 -0
- package/dist/cjs/core/blockin.spec.js.map +1 -0
- package/dist/cjs/core/coin.spec.d.ts +2 -0
- package/dist/cjs/core/coin.spec.d.ts.map +1 -0
- package/dist/cjs/core/coin.spec.js +80 -0
- package/dist/cjs/core/coin.spec.js.map +1 -0
- package/dist/cjs/core/cosmos-wrappers.spec.d.ts +2 -0
- package/dist/cjs/core/cosmos-wrappers.spec.d.ts.map +1 -0
- package/dist/cjs/core/cosmos-wrappers.spec.js +623 -0
- package/dist/cjs/core/cosmos-wrappers.spec.js.map +1 -0
- package/dist/cjs/core/managersplitter.spec.d.ts +2 -0
- package/dist/cjs/core/managersplitter.spec.d.ts.map +1 -0
- package/dist/cjs/core/managersplitter.spec.js +170 -0
- package/dist/cjs/core/managersplitter.spec.js.map +1 -0
- package/dist/cjs/core/overlaps.spec.js +201 -0
- package/dist/cjs/core/overlaps.spec.js.map +1 -1
- package/dist/cjs/core/permission-utils.spec.d.ts +2 -0
- package/dist/cjs/core/permission-utils.spec.d.ts.map +1 -0
- package/dist/cjs/core/permission-utils.spec.js +192 -0
- package/dist/cjs/core/permission-utils.spec.js.map +1 -0
- package/dist/cjs/core/permissions.js +4 -4
- package/dist/cjs/core/permissions.js.map +1 -1
- package/dist/cjs/core/permissions.spec.d.ts +2 -0
- package/dist/cjs/core/permissions.spec.d.ts.map +1 -0
- package/dist/cjs/core/permissions.spec.js +2051 -0
- package/dist/cjs/core/permissions.spec.js.map +1 -0
- package/dist/cjs/core/transfers.d.ts.map +1 -1
- package/dist/cjs/core/transfers.js +11 -7
- package/dist/cjs/core/transfers.js.map +1 -1
- package/dist/cjs/core/transfers.spec.js +647 -0
- package/dist/cjs/core/transfers.spec.js.map +1 -1
- package/dist/cjs/core/userBalances.spec.d.ts +2 -0
- package/dist/cjs/core/userBalances.spec.d.ts.map +1 -0
- package/dist/cjs/core/userBalances.spec.js +184 -0
- package/dist/cjs/core/userBalances.spec.js.map +1 -0
- package/dist/cjs/core/validate-utils.spec.d.ts +2 -0
- package/dist/cjs/core/validate-utils.spec.d.ts.map +1 -0
- package/dist/cjs/core/validate-utils.spec.js +202 -0
- package/dist/cjs/core/validate-utils.spec.js.map +1 -0
- package/dist/cjs/tsconfig.build.tsbuildinfo +1 -1
- package/dist/esm/api-indexer/BitBadgesCollection.d.ts +1 -0
- package/dist/esm/api-indexer/BitBadgesCollection.d.ts.map +1 -1
- package/dist/esm/api-indexer/BitBadgesCollection.js +4 -1
- package/dist/esm/api-indexer/BitBadgesCollection.js.map +1 -1
- package/dist/esm/core/approval-utils.spec.d.ts +2 -0
- package/dist/esm/core/approval-utils.spec.d.ts.map +1 -0
- package/dist/esm/core/approval-utils.spec.js +238 -0
- package/dist/esm/core/approval-utils.spec.js.map +1 -0
- package/dist/esm/core/approvals.spec.js +97 -1
- package/dist/esm/core/approvals.spec.js.map +1 -1
- package/dist/esm/core/bids.spec.d.ts +2 -0
- package/dist/esm/core/bids.spec.d.ts.map +1 -0
- package/dist/esm/core/bids.spec.js +199 -0
- package/dist/esm/core/bids.spec.js.map +1 -0
- package/dist/esm/core/blockin.spec.d.ts +2 -0
- package/dist/esm/core/blockin.spec.d.ts.map +1 -0
- package/dist/esm/core/blockin.spec.js +161 -0
- package/dist/esm/core/blockin.spec.js.map +1 -0
- package/dist/esm/core/coin.spec.d.ts +2 -0
- package/dist/esm/core/coin.spec.d.ts.map +1 -0
- package/dist/esm/core/coin.spec.js +78 -0
- package/dist/esm/core/coin.spec.js.map +1 -0
- package/dist/esm/core/cosmos-wrappers.spec.d.ts +2 -0
- package/dist/esm/core/cosmos-wrappers.spec.d.ts.map +1 -0
- package/dist/esm/core/cosmos-wrappers.spec.js +621 -0
- package/dist/esm/core/cosmos-wrappers.spec.js.map +1 -0
- package/dist/esm/core/managersplitter.spec.d.ts +2 -0
- package/dist/esm/core/managersplitter.spec.d.ts.map +1 -0
- package/dist/esm/core/managersplitter.spec.js +168 -0
- package/dist/esm/core/managersplitter.spec.js.map +1 -0
- package/dist/esm/core/overlaps.spec.js +202 -1
- package/dist/esm/core/overlaps.spec.js.map +1 -1
- package/dist/esm/core/permission-utils.spec.d.ts +2 -0
- package/dist/esm/core/permission-utils.spec.d.ts.map +1 -0
- package/dist/esm/core/permission-utils.spec.js +190 -0
- package/dist/esm/core/permission-utils.spec.js.map +1 -0
- package/dist/esm/core/permissions.js +4 -4
- package/dist/esm/core/permissions.js.map +1 -1
- package/dist/esm/core/permissions.spec.d.ts +2 -0
- package/dist/esm/core/permissions.spec.d.ts.map +1 -0
- package/dist/esm/core/permissions.spec.js +2049 -0
- package/dist/esm/core/permissions.spec.js.map +1 -0
- package/dist/esm/core/transfers.d.ts.map +1 -1
- package/dist/esm/core/transfers.js +11 -7
- package/dist/esm/core/transfers.js.map +1 -1
- package/dist/esm/core/transfers.spec.js +648 -1
- package/dist/esm/core/transfers.spec.js.map +1 -1
- package/dist/esm/core/userBalances.spec.d.ts +2 -0
- package/dist/esm/core/userBalances.spec.d.ts.map +1 -0
- package/dist/esm/core/userBalances.spec.js +182 -0
- package/dist/esm/core/userBalances.spec.js.map +1 -0
- package/dist/esm/core/validate-utils.spec.d.ts +2 -0
- package/dist/esm/core/validate-utils.spec.d.ts.map +1 -0
- package/dist/esm/core/validate-utils.spec.js +200 -0
- package/dist/esm/core/validate-utils.spec.js.map +1 -0
- package/dist/esm/tsconfig-esm.build.tsbuildinfo +1 -1
- package/package.json +4 -5
|
@@ -0,0 +1,2049 @@
|
|
|
1
|
+
import { genTestAddress } from './addressLists.spec.js';
|
|
2
|
+
import { AddressList } from './addressLists.js';
|
|
3
|
+
import { ActionPermission, TokenIdsActionPermission, CollectionApprovalPermission, CollectionApprovalPermissionWithDetails, CollectionPermissions, CollectionPermissionsWithDetails, UserPermissions, UserPermissionsWithDetails, UserOutgoingApprovalPermission, UserOutgoingApprovalPermissionWithDetails, UserIncomingApprovalPermission, UserIncomingApprovalPermissionWithDetails } from './permissions.js';
|
|
4
|
+
import { UintRangeArray } from './uintRanges.js';
|
|
5
|
+
import { BigIntify, Stringify } from '../common/string-numbers.js';
|
|
6
|
+
BigInt.prototype.toJSON = function () {
|
|
7
|
+
return this.toString();
|
|
8
|
+
};
|
|
9
|
+
const fullRange = () => UintRangeArray.From([{ start: 1n, end: 18446744073709551615n }]);
|
|
10
|
+
const allAddresses = () => new AddressList({
|
|
11
|
+
listId: 'All',
|
|
12
|
+
addresses: [],
|
|
13
|
+
whitelist: false,
|
|
14
|
+
uri: '',
|
|
15
|
+
customData: '',
|
|
16
|
+
createdBy: ''
|
|
17
|
+
});
|
|
18
|
+
const whitelistOf = (addresses) => new AddressList({
|
|
19
|
+
listId: 'custom',
|
|
20
|
+
addresses,
|
|
21
|
+
whitelist: true,
|
|
22
|
+
uri: '',
|
|
23
|
+
customData: '',
|
|
24
|
+
createdBy: ''
|
|
25
|
+
});
|
|
26
|
+
describe('ActionPermission', () => {
|
|
27
|
+
describe('construction', () => {
|
|
28
|
+
it('should create an instance with empty times', () => {
|
|
29
|
+
const perm = new ActionPermission({
|
|
30
|
+
permanentlyPermittedTimes: [],
|
|
31
|
+
permanentlyForbiddenTimes: []
|
|
32
|
+
});
|
|
33
|
+
expect(perm).toBeTruthy();
|
|
34
|
+
expect(perm.permanentlyPermittedTimes.length).toBe(0);
|
|
35
|
+
expect(perm.permanentlyForbiddenTimes.length).toBe(0);
|
|
36
|
+
});
|
|
37
|
+
it('should create an instance with permitted times', () => {
|
|
38
|
+
const perm = new ActionPermission({
|
|
39
|
+
permanentlyPermittedTimes: [{ start: 1n, end: 100n }],
|
|
40
|
+
permanentlyForbiddenTimes: []
|
|
41
|
+
});
|
|
42
|
+
expect(perm.permanentlyPermittedTimes.length).toBe(1);
|
|
43
|
+
expect(perm.permanentlyPermittedTimes[0].start).toBe(1n);
|
|
44
|
+
expect(perm.permanentlyPermittedTimes[0].end).toBe(100n);
|
|
45
|
+
});
|
|
46
|
+
it('should create an instance with forbidden times', () => {
|
|
47
|
+
const perm = new ActionPermission({
|
|
48
|
+
permanentlyPermittedTimes: [],
|
|
49
|
+
permanentlyForbiddenTimes: [{ start: 1n, end: 18446744073709551615n }]
|
|
50
|
+
});
|
|
51
|
+
expect(perm.permanentlyForbiddenTimes.length).toBe(1);
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
describe('castToUniversalPermission', () => {
|
|
55
|
+
it('should cast to universal permission with all uses flags false', () => {
|
|
56
|
+
const perm = new ActionPermission({
|
|
57
|
+
permanentlyPermittedTimes: [{ start: 1n, end: 100n }],
|
|
58
|
+
permanentlyForbiddenTimes: []
|
|
59
|
+
});
|
|
60
|
+
const universal = perm.castToUniversalPermission();
|
|
61
|
+
expect(universal.usesTokenIds).toBe(false);
|
|
62
|
+
expect(universal.usesTimelineTimes).toBe(false);
|
|
63
|
+
expect(universal.usesTransferTimes).toBe(false);
|
|
64
|
+
expect(universal.usesToList).toBe(false);
|
|
65
|
+
expect(universal.usesFromList).toBe(false);
|
|
66
|
+
expect(universal.usesInitiatedByList).toBe(false);
|
|
67
|
+
expect(universal.usesOwnershipTimes).toBe(false);
|
|
68
|
+
expect(universal.usesApprovalIdList).toBe(false);
|
|
69
|
+
});
|
|
70
|
+
it('should preserve permitted/forbidden times in cast', () => {
|
|
71
|
+
const perm = new ActionPermission({
|
|
72
|
+
permanentlyPermittedTimes: [{ start: 10n, end: 20n }],
|
|
73
|
+
permanentlyForbiddenTimes: [{ start: 30n, end: 40n }]
|
|
74
|
+
});
|
|
75
|
+
const universal = perm.castToUniversalPermission();
|
|
76
|
+
expect(universal.permanentlyPermittedTimes[0].start).toBe(10n);
|
|
77
|
+
expect(universal.permanentlyPermittedTimes[0].end).toBe(20n);
|
|
78
|
+
expect(universal.permanentlyForbiddenTimes[0].start).toBe(30n);
|
|
79
|
+
expect(universal.permanentlyForbiddenTimes[0].end).toBe(40n);
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
describe('validateUpdate', () => {
|
|
83
|
+
it('should allow identical permissions (no change)', () => {
|
|
84
|
+
const perms = [
|
|
85
|
+
new ActionPermission({
|
|
86
|
+
permanentlyPermittedTimes: [{ start: 1n, end: 100n }],
|
|
87
|
+
permanentlyForbiddenTimes: []
|
|
88
|
+
})
|
|
89
|
+
];
|
|
90
|
+
const err = ActionPermission.validateUpdate(perms, perms);
|
|
91
|
+
expect(err).toBeNull();
|
|
92
|
+
});
|
|
93
|
+
it('should allow adding new permissions that were not previously defined', () => {
|
|
94
|
+
const oldPerms = [];
|
|
95
|
+
const newPerms = [
|
|
96
|
+
new ActionPermission({
|
|
97
|
+
permanentlyPermittedTimes: [{ start: 1n, end: 100n }],
|
|
98
|
+
permanentlyForbiddenTimes: []
|
|
99
|
+
})
|
|
100
|
+
];
|
|
101
|
+
const err = ActionPermission.validateUpdate(oldPerms, newPerms);
|
|
102
|
+
expect(err).toBeNull();
|
|
103
|
+
});
|
|
104
|
+
it('should reject removing previously defined permissions', () => {
|
|
105
|
+
const oldPerms = [
|
|
106
|
+
new ActionPermission({
|
|
107
|
+
permanentlyPermittedTimes: [{ start: 1n, end: 100n }],
|
|
108
|
+
permanentlyForbiddenTimes: []
|
|
109
|
+
})
|
|
110
|
+
];
|
|
111
|
+
const newPerms = [];
|
|
112
|
+
const err = ActionPermission.validateUpdate(oldPerms, newPerms);
|
|
113
|
+
expect(err).not.toBeNull();
|
|
114
|
+
});
|
|
115
|
+
it('should reject changing permanently permitted times to forbidden', () => {
|
|
116
|
+
const oldPerms = [
|
|
117
|
+
new ActionPermission({
|
|
118
|
+
permanentlyPermittedTimes: [{ start: 1n, end: 100n }],
|
|
119
|
+
permanentlyForbiddenTimes: []
|
|
120
|
+
})
|
|
121
|
+
];
|
|
122
|
+
const newPerms = [
|
|
123
|
+
new ActionPermission({
|
|
124
|
+
permanentlyPermittedTimes: [],
|
|
125
|
+
permanentlyForbiddenTimes: [{ start: 1n, end: 100n }]
|
|
126
|
+
})
|
|
127
|
+
];
|
|
128
|
+
const err = ActionPermission.validateUpdate(oldPerms, newPerms);
|
|
129
|
+
expect(err).not.toBeNull();
|
|
130
|
+
});
|
|
131
|
+
it('should reject changing permanently forbidden times to permitted', () => {
|
|
132
|
+
const oldPerms = [
|
|
133
|
+
new ActionPermission({
|
|
134
|
+
permanentlyPermittedTimes: [],
|
|
135
|
+
permanentlyForbiddenTimes: [{ start: 1n, end: 100n }]
|
|
136
|
+
})
|
|
137
|
+
];
|
|
138
|
+
const newPerms = [
|
|
139
|
+
new ActionPermission({
|
|
140
|
+
permanentlyPermittedTimes: [{ start: 1n, end: 100n }],
|
|
141
|
+
permanentlyForbiddenTimes: []
|
|
142
|
+
})
|
|
143
|
+
];
|
|
144
|
+
const err = ActionPermission.validateUpdate(oldPerms, newPerms);
|
|
145
|
+
expect(err).not.toBeNull();
|
|
146
|
+
});
|
|
147
|
+
it('should allow extending permitted times (adding more times)', () => {
|
|
148
|
+
const oldPerms = [
|
|
149
|
+
new ActionPermission({
|
|
150
|
+
permanentlyPermittedTimes: [{ start: 1n, end: 50n }],
|
|
151
|
+
permanentlyForbiddenTimes: []
|
|
152
|
+
})
|
|
153
|
+
];
|
|
154
|
+
const newPerms = [
|
|
155
|
+
new ActionPermission({
|
|
156
|
+
permanentlyPermittedTimes: [{ start: 1n, end: 100n }],
|
|
157
|
+
permanentlyForbiddenTimes: []
|
|
158
|
+
})
|
|
159
|
+
];
|
|
160
|
+
const err = ActionPermission.validateUpdate(oldPerms, newPerms);
|
|
161
|
+
expect(err).toBeNull();
|
|
162
|
+
});
|
|
163
|
+
it('should allow extending forbidden times (adding more times)', () => {
|
|
164
|
+
const oldPerms = [
|
|
165
|
+
new ActionPermission({
|
|
166
|
+
permanentlyPermittedTimes: [],
|
|
167
|
+
permanentlyForbiddenTimes: [{ start: 1n, end: 50n }]
|
|
168
|
+
})
|
|
169
|
+
];
|
|
170
|
+
const newPerms = [
|
|
171
|
+
new ActionPermission({
|
|
172
|
+
permanentlyPermittedTimes: [],
|
|
173
|
+
permanentlyForbiddenTimes: [{ start: 1n, end: 100n }]
|
|
174
|
+
})
|
|
175
|
+
];
|
|
176
|
+
const err = ActionPermission.validateUpdate(oldPerms, newPerms);
|
|
177
|
+
expect(err).toBeNull();
|
|
178
|
+
});
|
|
179
|
+
it('should reject shrinking permitted times', () => {
|
|
180
|
+
const oldPerms = [
|
|
181
|
+
new ActionPermission({
|
|
182
|
+
permanentlyPermittedTimes: [{ start: 1n, end: 100n }],
|
|
183
|
+
permanentlyForbiddenTimes: []
|
|
184
|
+
})
|
|
185
|
+
];
|
|
186
|
+
const newPerms = [
|
|
187
|
+
new ActionPermission({
|
|
188
|
+
permanentlyPermittedTimes: [{ start: 1n, end: 50n }],
|
|
189
|
+
permanentlyForbiddenTimes: []
|
|
190
|
+
})
|
|
191
|
+
];
|
|
192
|
+
const err = ActionPermission.validateUpdate(oldPerms, newPerms);
|
|
193
|
+
expect(err).not.toBeNull();
|
|
194
|
+
});
|
|
195
|
+
it('should reject shrinking forbidden times', () => {
|
|
196
|
+
const oldPerms = [
|
|
197
|
+
new ActionPermission({
|
|
198
|
+
permanentlyPermittedTimes: [],
|
|
199
|
+
permanentlyForbiddenTimes: [{ start: 1n, end: 100n }]
|
|
200
|
+
})
|
|
201
|
+
];
|
|
202
|
+
const newPerms = [
|
|
203
|
+
new ActionPermission({
|
|
204
|
+
permanentlyPermittedTimes: [],
|
|
205
|
+
permanentlyForbiddenTimes: [{ start: 1n, end: 50n }]
|
|
206
|
+
})
|
|
207
|
+
];
|
|
208
|
+
const err = ActionPermission.validateUpdate(oldPerms, newPerms);
|
|
209
|
+
expect(err).not.toBeNull();
|
|
210
|
+
});
|
|
211
|
+
});
|
|
212
|
+
describe('check', () => {
|
|
213
|
+
it('should return null when no permissions are defined (neutral)', () => {
|
|
214
|
+
const err = ActionPermission.check([]);
|
|
215
|
+
expect(err).toBeNull();
|
|
216
|
+
});
|
|
217
|
+
it('should return null when action is permanently permitted at current time', () => {
|
|
218
|
+
const now = BigInt(Date.now());
|
|
219
|
+
const perms = [
|
|
220
|
+
new ActionPermission({
|
|
221
|
+
permanentlyPermittedTimes: [{ start: 1n, end: now + 1000000n }],
|
|
222
|
+
permanentlyForbiddenTimes: []
|
|
223
|
+
})
|
|
224
|
+
];
|
|
225
|
+
const err = ActionPermission.check(perms, now);
|
|
226
|
+
expect(err).toBeNull();
|
|
227
|
+
});
|
|
228
|
+
it('should return error when action is permanently forbidden at given time', () => {
|
|
229
|
+
const checkTime = 50n;
|
|
230
|
+
const perms = [
|
|
231
|
+
new ActionPermission({
|
|
232
|
+
permanentlyPermittedTimes: [],
|
|
233
|
+
permanentlyForbiddenTimes: [{ start: 1n, end: 100n }]
|
|
234
|
+
})
|
|
235
|
+
];
|
|
236
|
+
const err = ActionPermission.check(perms, checkTime);
|
|
237
|
+
expect(err).not.toBeNull();
|
|
238
|
+
expect(err.message).toContain('forbidden');
|
|
239
|
+
});
|
|
240
|
+
it('should return null when action is forbidden at a different time', () => {
|
|
241
|
+
const checkTime = 200n;
|
|
242
|
+
const perms = [
|
|
243
|
+
new ActionPermission({
|
|
244
|
+
permanentlyPermittedTimes: [],
|
|
245
|
+
permanentlyForbiddenTimes: [{ start: 1n, end: 100n }]
|
|
246
|
+
})
|
|
247
|
+
];
|
|
248
|
+
const err = ActionPermission.check(perms, checkTime);
|
|
249
|
+
expect(err).toBeNull();
|
|
250
|
+
});
|
|
251
|
+
it('should return error when forbidden covers all time', () => {
|
|
252
|
+
const perms = [
|
|
253
|
+
new ActionPermission({
|
|
254
|
+
permanentlyPermittedTimes: [],
|
|
255
|
+
permanentlyForbiddenTimes: [{ start: 1n, end: 18446744073709551615n }]
|
|
256
|
+
})
|
|
257
|
+
];
|
|
258
|
+
const err = ActionPermission.check(perms, 500n);
|
|
259
|
+
expect(err).not.toBeNull();
|
|
260
|
+
});
|
|
261
|
+
});
|
|
262
|
+
});
|
|
263
|
+
describe('TokenIdsActionPermission', () => {
|
|
264
|
+
describe('construction', () => {
|
|
265
|
+
it('should create an instance with token IDs and times', () => {
|
|
266
|
+
const perm = new TokenIdsActionPermission({
|
|
267
|
+
tokenIds: [{ start: 1n, end: 10n }],
|
|
268
|
+
permanentlyPermittedTimes: [{ start: 1n, end: 100n }],
|
|
269
|
+
permanentlyForbiddenTimes: []
|
|
270
|
+
});
|
|
271
|
+
expect(perm).toBeTruthy();
|
|
272
|
+
expect(perm.tokenIds.length).toBe(1);
|
|
273
|
+
expect(perm.tokenIds[0].start).toBe(1n);
|
|
274
|
+
expect(perm.tokenIds[0].end).toBe(10n);
|
|
275
|
+
});
|
|
276
|
+
});
|
|
277
|
+
describe('castToUniversalPermission', () => {
|
|
278
|
+
it('should set usesTokenIds to true', () => {
|
|
279
|
+
const perm = new TokenIdsActionPermission({
|
|
280
|
+
tokenIds: [{ start: 1n, end: 10n }],
|
|
281
|
+
permanentlyPermittedTimes: [],
|
|
282
|
+
permanentlyForbiddenTimes: []
|
|
283
|
+
});
|
|
284
|
+
const universal = perm.castToUniversalPermission();
|
|
285
|
+
expect(universal.usesTokenIds).toBe(true);
|
|
286
|
+
expect(universal.usesTimelineTimes).toBe(false);
|
|
287
|
+
expect(universal.usesTransferTimes).toBe(false);
|
|
288
|
+
});
|
|
289
|
+
});
|
|
290
|
+
describe('validateUpdate', () => {
|
|
291
|
+
it('should allow identical permissions', () => {
|
|
292
|
+
const perms = [
|
|
293
|
+
new TokenIdsActionPermission({
|
|
294
|
+
tokenIds: [{ start: 1n, end: 10n }],
|
|
295
|
+
permanentlyPermittedTimes: [{ start: 1n, end: 100n }],
|
|
296
|
+
permanentlyForbiddenTimes: []
|
|
297
|
+
})
|
|
298
|
+
];
|
|
299
|
+
const err = TokenIdsActionPermission.validateUpdate(perms, perms);
|
|
300
|
+
expect(err).toBeNull();
|
|
301
|
+
});
|
|
302
|
+
it('should reject removing a permission with tokenIds', () => {
|
|
303
|
+
const oldPerms = [
|
|
304
|
+
new TokenIdsActionPermission({
|
|
305
|
+
tokenIds: [{ start: 1n, end: 10n }],
|
|
306
|
+
permanentlyPermittedTimes: [{ start: 1n, end: 100n }],
|
|
307
|
+
permanentlyForbiddenTimes: []
|
|
308
|
+
})
|
|
309
|
+
];
|
|
310
|
+
const newPerms = [];
|
|
311
|
+
const err = TokenIdsActionPermission.validateUpdate(oldPerms, newPerms);
|
|
312
|
+
expect(err).not.toBeNull();
|
|
313
|
+
});
|
|
314
|
+
it('should reject changing permitted to forbidden for same token IDs', () => {
|
|
315
|
+
const oldPerms = [
|
|
316
|
+
new TokenIdsActionPermission({
|
|
317
|
+
tokenIds: [{ start: 1n, end: 10n }],
|
|
318
|
+
permanentlyPermittedTimes: [{ start: 1n, end: 100n }],
|
|
319
|
+
permanentlyForbiddenTimes: []
|
|
320
|
+
})
|
|
321
|
+
];
|
|
322
|
+
const newPerms = [
|
|
323
|
+
new TokenIdsActionPermission({
|
|
324
|
+
tokenIds: [{ start: 1n, end: 10n }],
|
|
325
|
+
permanentlyPermittedTimes: [],
|
|
326
|
+
permanentlyForbiddenTimes: [{ start: 1n, end: 100n }]
|
|
327
|
+
})
|
|
328
|
+
];
|
|
329
|
+
const err = TokenIdsActionPermission.validateUpdate(oldPerms, newPerms);
|
|
330
|
+
expect(err).not.toBeNull();
|
|
331
|
+
});
|
|
332
|
+
});
|
|
333
|
+
describe('check', () => {
|
|
334
|
+
it('should return null when no permissions forbid the action', () => {
|
|
335
|
+
const perms = [
|
|
336
|
+
new TokenIdsActionPermission({
|
|
337
|
+
tokenIds: [{ start: 1n, end: 10n }],
|
|
338
|
+
permanentlyPermittedTimes: [{ start: 1n, end: 100n }],
|
|
339
|
+
permanentlyForbiddenTimes: []
|
|
340
|
+
})
|
|
341
|
+
];
|
|
342
|
+
const err = TokenIdsActionPermission.check([{ tokenIds: UintRangeArray.From([{ start: 1n, end: 5n }]) }], perms, 50n);
|
|
343
|
+
expect(err).toBeNull();
|
|
344
|
+
});
|
|
345
|
+
it('should return error when forbidden for the requested token IDs', () => {
|
|
346
|
+
const perms = [
|
|
347
|
+
new TokenIdsActionPermission({
|
|
348
|
+
tokenIds: [{ start: 1n, end: 10n }],
|
|
349
|
+
permanentlyPermittedTimes: [],
|
|
350
|
+
permanentlyForbiddenTimes: [{ start: 1n, end: 18446744073709551615n }]
|
|
351
|
+
})
|
|
352
|
+
];
|
|
353
|
+
const err = TokenIdsActionPermission.check([{ tokenIds: UintRangeArray.From([{ start: 5n, end: 5n }]) }], perms, 50n);
|
|
354
|
+
expect(err).not.toBeNull();
|
|
355
|
+
expect(err.message).toContain('forbidden');
|
|
356
|
+
});
|
|
357
|
+
it('should return null when checking token IDs not covered by forbidden permission', () => {
|
|
358
|
+
const perms = [
|
|
359
|
+
new TokenIdsActionPermission({
|
|
360
|
+
tokenIds: [{ start: 1n, end: 10n }],
|
|
361
|
+
permanentlyPermittedTimes: [],
|
|
362
|
+
permanentlyForbiddenTimes: [{ start: 1n, end: 18446744073709551615n }]
|
|
363
|
+
})
|
|
364
|
+
];
|
|
365
|
+
const err = TokenIdsActionPermission.check([{ tokenIds: UintRangeArray.From([{ start: 20n, end: 20n }]) }], perms, 50n);
|
|
366
|
+
expect(err).toBeNull();
|
|
367
|
+
});
|
|
368
|
+
});
|
|
369
|
+
});
|
|
370
|
+
describe('CollectionApprovalPermissionWithDetails', () => {
|
|
371
|
+
const makeApprovalPerm = (opts) => {
|
|
372
|
+
return new CollectionApprovalPermissionWithDetails({
|
|
373
|
+
fromListId: 'All',
|
|
374
|
+
toListId: 'All',
|
|
375
|
+
initiatedByListId: 'All',
|
|
376
|
+
approvalId: 'All',
|
|
377
|
+
tokenIds: (opts.tokenIds || [[1n, 18446744073709551615n]]).map(([s, e]) => ({ start: s, end: e })),
|
|
378
|
+
transferTimes: (opts.transferTimes || [[1n, 18446744073709551615n]]).map(([s, e]) => ({ start: s, end: e })),
|
|
379
|
+
ownershipTimes: (opts.ownershipTimes || [[1n, 18446744073709551615n]]).map(([s, e]) => ({ start: s, end: e })),
|
|
380
|
+
permanentlyPermittedTimes: (opts.permitted || []).map(([s, e]) => ({ start: s, end: e })),
|
|
381
|
+
permanentlyForbiddenTimes: (opts.forbidden || []).map(([s, e]) => ({ start: s, end: e })),
|
|
382
|
+
fromList: allAddresses(),
|
|
383
|
+
toList: allAddresses(),
|
|
384
|
+
initiatedByList: allAddresses()
|
|
385
|
+
});
|
|
386
|
+
};
|
|
387
|
+
describe('construction', () => {
|
|
388
|
+
it('should create an instance with all fields', () => {
|
|
389
|
+
const perm = makeApprovalPerm({ permitted: [[1n, 100n]] });
|
|
390
|
+
expect(perm).toBeTruthy();
|
|
391
|
+
expect(perm.fromList).toBeTruthy();
|
|
392
|
+
expect(perm.toList).toBeTruthy();
|
|
393
|
+
expect(perm.initiatedByList).toBeTruthy();
|
|
394
|
+
});
|
|
395
|
+
});
|
|
396
|
+
describe('castToUniversalPermission', () => {
|
|
397
|
+
it('should set all uses flags to true', () => {
|
|
398
|
+
const perm = makeApprovalPerm({});
|
|
399
|
+
const universal = perm.castToUniversalPermission();
|
|
400
|
+
expect(universal.usesTokenIds).toBe(true);
|
|
401
|
+
expect(universal.usesTransferTimes).toBe(true);
|
|
402
|
+
expect(universal.usesOwnershipTimes).toBe(true);
|
|
403
|
+
expect(universal.usesToList).toBe(true);
|
|
404
|
+
expect(universal.usesFromList).toBe(true);
|
|
405
|
+
expect(universal.usesInitiatedByList).toBe(true);
|
|
406
|
+
expect(universal.usesApprovalIdList).toBe(true);
|
|
407
|
+
});
|
|
408
|
+
});
|
|
409
|
+
describe('validateUpdate', () => {
|
|
410
|
+
it('should allow identical approval permissions', () => {
|
|
411
|
+
const perms = [makeApprovalPerm({ permitted: [[1n, 100n]] })];
|
|
412
|
+
const err = CollectionApprovalPermission.validateUpdate(perms, perms);
|
|
413
|
+
expect(err).toBeNull();
|
|
414
|
+
});
|
|
415
|
+
it('should reject removing approval permissions', () => {
|
|
416
|
+
const oldPerms = [makeApprovalPerm({ permitted: [[1n, 100n]] })];
|
|
417
|
+
const newPerms = [];
|
|
418
|
+
const err = CollectionApprovalPermission.validateUpdate(oldPerms, newPerms);
|
|
419
|
+
expect(err).not.toBeNull();
|
|
420
|
+
});
|
|
421
|
+
it('should reject changing permitted to forbidden for approvals', () => {
|
|
422
|
+
const oldPerms = [makeApprovalPerm({ permitted: [[1n, 100n]] })];
|
|
423
|
+
const newPerms = [makeApprovalPerm({ forbidden: [[1n, 100n]] })];
|
|
424
|
+
const err = CollectionApprovalPermission.validateUpdate(oldPerms, newPerms);
|
|
425
|
+
expect(err).not.toBeNull();
|
|
426
|
+
});
|
|
427
|
+
it('should allow extending permitted times for approvals', () => {
|
|
428
|
+
const oldPerms = [makeApprovalPerm({ permitted: [[1n, 50n]] })];
|
|
429
|
+
const newPerms = [makeApprovalPerm({ permitted: [[1n, 100n]] })];
|
|
430
|
+
const err = CollectionApprovalPermission.validateUpdate(oldPerms, newPerms);
|
|
431
|
+
expect(err).toBeNull();
|
|
432
|
+
});
|
|
433
|
+
});
|
|
434
|
+
describe('check', () => {
|
|
435
|
+
it('should return null when approvals are permitted', () => {
|
|
436
|
+
const perms = [makeApprovalPerm({ permitted: [[1n, 18446744073709551615n]] })];
|
|
437
|
+
const err = CollectionApprovalPermission.check([
|
|
438
|
+
{
|
|
439
|
+
tokenIds: UintRangeArray.From([{ start: 1n, end: 10n }]),
|
|
440
|
+
ownershipTimes: fullRange(),
|
|
441
|
+
transferTimes: fullRange(),
|
|
442
|
+
toList: allAddresses(),
|
|
443
|
+
fromList: allAddresses(),
|
|
444
|
+
initiatedByList: allAddresses(),
|
|
445
|
+
approvalIdList: allAddresses()
|
|
446
|
+
}
|
|
447
|
+
], perms, 50n);
|
|
448
|
+
expect(err).toBeNull();
|
|
449
|
+
});
|
|
450
|
+
it('should return error when approvals are forbidden', () => {
|
|
451
|
+
const perms = [makeApprovalPerm({ forbidden: [[1n, 18446744073709551615n]] })];
|
|
452
|
+
const err = CollectionApprovalPermission.check([
|
|
453
|
+
{
|
|
454
|
+
tokenIds: UintRangeArray.From([{ start: 1n, end: 10n }]),
|
|
455
|
+
ownershipTimes: fullRange(),
|
|
456
|
+
transferTimes: fullRange(),
|
|
457
|
+
toList: allAddresses(),
|
|
458
|
+
fromList: allAddresses(),
|
|
459
|
+
initiatedByList: allAddresses(),
|
|
460
|
+
approvalIdList: allAddresses()
|
|
461
|
+
}
|
|
462
|
+
], perms, 50n);
|
|
463
|
+
expect(err).not.toBeNull();
|
|
464
|
+
expect(err.message).toContain('forbidden');
|
|
465
|
+
});
|
|
466
|
+
it('should return null when checking at a time outside forbidden range', () => {
|
|
467
|
+
const perms = [makeApprovalPerm({ forbidden: [[1n, 100n]] })];
|
|
468
|
+
const err = CollectionApprovalPermission.check([
|
|
469
|
+
{
|
|
470
|
+
tokenIds: UintRangeArray.From([{ start: 1n, end: 10n }]),
|
|
471
|
+
ownershipTimes: fullRange(),
|
|
472
|
+
transferTimes: fullRange(),
|
|
473
|
+
toList: allAddresses(),
|
|
474
|
+
fromList: allAddresses(),
|
|
475
|
+
initiatedByList: allAddresses(),
|
|
476
|
+
approvalIdList: allAddresses()
|
|
477
|
+
}
|
|
478
|
+
], perms, 200n);
|
|
479
|
+
expect(err).toBeNull();
|
|
480
|
+
});
|
|
481
|
+
});
|
|
482
|
+
});
|
|
483
|
+
describe('UserPermissions', () => {
|
|
484
|
+
describe('construction', () => {
|
|
485
|
+
it('should create an instance with empty arrays', () => {
|
|
486
|
+
const perms = UserPermissions.InitEmpty();
|
|
487
|
+
expect(perms).toBeTruthy();
|
|
488
|
+
expect(perms.canUpdateOutgoingApprovals.length).toBe(0);
|
|
489
|
+
expect(perms.canUpdateIncomingApprovals.length).toBe(0);
|
|
490
|
+
expect(perms.canUpdateAutoApproveSelfInitiatedOutgoingTransfers.length).toBe(0);
|
|
491
|
+
expect(perms.canUpdateAutoApproveSelfInitiatedIncomingTransfers.length).toBe(0);
|
|
492
|
+
expect(perms.canUpdateAutoApproveAllIncomingTransfers.length).toBe(0);
|
|
493
|
+
});
|
|
494
|
+
});
|
|
495
|
+
describe('validateUpdate', () => {
|
|
496
|
+
it('should allow empty to empty update', () => {
|
|
497
|
+
const makeEmpty = () => new UserPermissionsWithDetails({
|
|
498
|
+
canUpdateOutgoingApprovals: [],
|
|
499
|
+
canUpdateIncomingApprovals: [],
|
|
500
|
+
canUpdateAutoApproveSelfInitiatedOutgoingTransfers: [],
|
|
501
|
+
canUpdateAutoApproveSelfInitiatedIncomingTransfers: [],
|
|
502
|
+
canUpdateAutoApproveAllIncomingTransfers: []
|
|
503
|
+
});
|
|
504
|
+
const err = UserPermissions.validateUpdate(makeEmpty(), makeEmpty());
|
|
505
|
+
expect(err).toBeNull();
|
|
506
|
+
});
|
|
507
|
+
it('should reject removing auto-approve permission', () => {
|
|
508
|
+
const oldPerms = new UserPermissionsWithDetails({
|
|
509
|
+
canUpdateOutgoingApprovals: [],
|
|
510
|
+
canUpdateIncomingApprovals: [],
|
|
511
|
+
canUpdateAutoApproveSelfInitiatedOutgoingTransfers: [
|
|
512
|
+
new ActionPermission({
|
|
513
|
+
permanentlyPermittedTimes: [{ start: 1n, end: 100n }],
|
|
514
|
+
permanentlyForbiddenTimes: []
|
|
515
|
+
})
|
|
516
|
+
],
|
|
517
|
+
canUpdateAutoApproveSelfInitiatedIncomingTransfers: [],
|
|
518
|
+
canUpdateAutoApproveAllIncomingTransfers: []
|
|
519
|
+
});
|
|
520
|
+
const newPerms = new UserPermissionsWithDetails({
|
|
521
|
+
canUpdateOutgoingApprovals: [],
|
|
522
|
+
canUpdateIncomingApprovals: [],
|
|
523
|
+
canUpdateAutoApproveSelfInitiatedOutgoingTransfers: [],
|
|
524
|
+
canUpdateAutoApproveSelfInitiatedIncomingTransfers: [],
|
|
525
|
+
canUpdateAutoApproveAllIncomingTransfers: []
|
|
526
|
+
});
|
|
527
|
+
const err = UserPermissions.validateUpdate(oldPerms, newPerms);
|
|
528
|
+
expect(err).not.toBeNull();
|
|
529
|
+
});
|
|
530
|
+
});
|
|
531
|
+
});
|
|
532
|
+
describe('CollectionPermissions', () => {
|
|
533
|
+
describe('construction', () => {
|
|
534
|
+
it('should create via InitEmpty', () => {
|
|
535
|
+
const perms = CollectionPermissions.InitEmpty();
|
|
536
|
+
expect(perms).toBeTruthy();
|
|
537
|
+
expect(perms.canDeleteCollection.length).toBe(0);
|
|
538
|
+
expect(perms.canArchiveCollection.length).toBe(0);
|
|
539
|
+
expect(perms.canUpdateStandards.length).toBe(0);
|
|
540
|
+
expect(perms.canUpdateCustomData.length).toBe(0);
|
|
541
|
+
expect(perms.canUpdateManager.length).toBe(0);
|
|
542
|
+
expect(perms.canUpdateCollectionMetadata.length).toBe(0);
|
|
543
|
+
expect(perms.canUpdateValidTokenIds.length).toBe(0);
|
|
544
|
+
expect(perms.canUpdateTokenMetadata.length).toBe(0);
|
|
545
|
+
expect(perms.canUpdateCollectionApprovals.length).toBe(0);
|
|
546
|
+
expect(perms.canAddMoreAliasPaths.length).toBe(0);
|
|
547
|
+
expect(perms.canAddMoreCosmosCoinWrapperPaths.length).toBe(0);
|
|
548
|
+
});
|
|
549
|
+
it('should construct with permissions', () => {
|
|
550
|
+
const perms = new CollectionPermissions({
|
|
551
|
+
canDeleteCollection: [
|
|
552
|
+
new ActionPermission({
|
|
553
|
+
permanentlyPermittedTimes: [],
|
|
554
|
+
permanentlyForbiddenTimes: [{ start: 1n, end: 18446744073709551615n }]
|
|
555
|
+
})
|
|
556
|
+
],
|
|
557
|
+
canArchiveCollection: [],
|
|
558
|
+
canUpdateStandards: [],
|
|
559
|
+
canUpdateCustomData: [],
|
|
560
|
+
canUpdateManager: [],
|
|
561
|
+
canUpdateCollectionMetadata: [],
|
|
562
|
+
canUpdateValidTokenIds: [],
|
|
563
|
+
canUpdateTokenMetadata: [],
|
|
564
|
+
canUpdateCollectionApprovals: [],
|
|
565
|
+
canAddMoreAliasPaths: [],
|
|
566
|
+
canAddMoreCosmosCoinWrapperPaths: []
|
|
567
|
+
});
|
|
568
|
+
expect(perms.canDeleteCollection.length).toBe(1);
|
|
569
|
+
});
|
|
570
|
+
});
|
|
571
|
+
describe('validateUpdate', () => {
|
|
572
|
+
it('should allow identical collection permissions', () => {
|
|
573
|
+
const makePerms = () => new CollectionPermissionsWithDetails({
|
|
574
|
+
canDeleteCollection: [
|
|
575
|
+
new ActionPermission({
|
|
576
|
+
permanentlyPermittedTimes: [{ start: 1n, end: 100n }],
|
|
577
|
+
permanentlyForbiddenTimes: []
|
|
578
|
+
})
|
|
579
|
+
],
|
|
580
|
+
canArchiveCollection: [],
|
|
581
|
+
canUpdateStandards: [],
|
|
582
|
+
canUpdateCustomData: [],
|
|
583
|
+
canUpdateManager: [],
|
|
584
|
+
canUpdateCollectionMetadata: [],
|
|
585
|
+
canUpdateValidTokenIds: [],
|
|
586
|
+
canUpdateTokenMetadata: [],
|
|
587
|
+
canUpdateCollectionApprovals: [],
|
|
588
|
+
canAddMoreAliasPaths: [],
|
|
589
|
+
canAddMoreCosmosCoinWrapperPaths: []
|
|
590
|
+
});
|
|
591
|
+
const err = CollectionPermissionsWithDetails.validateUpdate(makePerms(), makePerms());
|
|
592
|
+
expect(err).toBeNull();
|
|
593
|
+
});
|
|
594
|
+
it('should reject removing canDeleteCollection permission', () => {
|
|
595
|
+
const oldPerms = new CollectionPermissionsWithDetails({
|
|
596
|
+
canDeleteCollection: [
|
|
597
|
+
new ActionPermission({
|
|
598
|
+
permanentlyPermittedTimes: [{ start: 1n, end: 100n }],
|
|
599
|
+
permanentlyForbiddenTimes: []
|
|
600
|
+
})
|
|
601
|
+
],
|
|
602
|
+
canArchiveCollection: [],
|
|
603
|
+
canUpdateStandards: [],
|
|
604
|
+
canUpdateCustomData: [],
|
|
605
|
+
canUpdateManager: [],
|
|
606
|
+
canUpdateCollectionMetadata: [],
|
|
607
|
+
canUpdateValidTokenIds: [],
|
|
608
|
+
canUpdateTokenMetadata: [],
|
|
609
|
+
canUpdateCollectionApprovals: [],
|
|
610
|
+
canAddMoreAliasPaths: [],
|
|
611
|
+
canAddMoreCosmosCoinWrapperPaths: []
|
|
612
|
+
});
|
|
613
|
+
const newPerms = new CollectionPermissionsWithDetails({
|
|
614
|
+
canDeleteCollection: [],
|
|
615
|
+
canArchiveCollection: [],
|
|
616
|
+
canUpdateStandards: [],
|
|
617
|
+
canUpdateCustomData: [],
|
|
618
|
+
canUpdateManager: [],
|
|
619
|
+
canUpdateCollectionMetadata: [],
|
|
620
|
+
canUpdateValidTokenIds: [],
|
|
621
|
+
canUpdateTokenMetadata: [],
|
|
622
|
+
canUpdateCollectionApprovals: [],
|
|
623
|
+
canAddMoreAliasPaths: [],
|
|
624
|
+
canAddMoreCosmosCoinWrapperPaths: []
|
|
625
|
+
});
|
|
626
|
+
const err = CollectionPermissionsWithDetails.validateUpdate(oldPerms, newPerms);
|
|
627
|
+
expect(err).not.toBeNull();
|
|
628
|
+
});
|
|
629
|
+
it('should reject changing canUpdateManager from permitted to forbidden', () => {
|
|
630
|
+
const oldPerms = new CollectionPermissionsWithDetails({
|
|
631
|
+
canDeleteCollection: [],
|
|
632
|
+
canArchiveCollection: [],
|
|
633
|
+
canUpdateStandards: [],
|
|
634
|
+
canUpdateCustomData: [],
|
|
635
|
+
canUpdateManager: [
|
|
636
|
+
new ActionPermission({
|
|
637
|
+
permanentlyPermittedTimes: [{ start: 1n, end: 100n }],
|
|
638
|
+
permanentlyForbiddenTimes: []
|
|
639
|
+
})
|
|
640
|
+
],
|
|
641
|
+
canUpdateCollectionMetadata: [],
|
|
642
|
+
canUpdateValidTokenIds: [],
|
|
643
|
+
canUpdateTokenMetadata: [],
|
|
644
|
+
canUpdateCollectionApprovals: [],
|
|
645
|
+
canAddMoreAliasPaths: [],
|
|
646
|
+
canAddMoreCosmosCoinWrapperPaths: []
|
|
647
|
+
});
|
|
648
|
+
const newPerms = new CollectionPermissionsWithDetails({
|
|
649
|
+
canDeleteCollection: [],
|
|
650
|
+
canArchiveCollection: [],
|
|
651
|
+
canUpdateStandards: [],
|
|
652
|
+
canUpdateCustomData: [],
|
|
653
|
+
canUpdateManager: [
|
|
654
|
+
new ActionPermission({
|
|
655
|
+
permanentlyPermittedTimes: [],
|
|
656
|
+
permanentlyForbiddenTimes: [{ start: 1n, end: 100n }]
|
|
657
|
+
})
|
|
658
|
+
],
|
|
659
|
+
canUpdateCollectionMetadata: [],
|
|
660
|
+
canUpdateValidTokenIds: [],
|
|
661
|
+
canUpdateTokenMetadata: [],
|
|
662
|
+
canUpdateCollectionApprovals: [],
|
|
663
|
+
canAddMoreAliasPaths: [],
|
|
664
|
+
canAddMoreCosmosCoinWrapperPaths: []
|
|
665
|
+
});
|
|
666
|
+
const err = CollectionPermissionsWithDetails.validateUpdate(oldPerms, newPerms);
|
|
667
|
+
expect(err).not.toBeNull();
|
|
668
|
+
});
|
|
669
|
+
it('should allow all-empty to all-empty', () => {
|
|
670
|
+
const makeEmpty = () => new CollectionPermissionsWithDetails({
|
|
671
|
+
canDeleteCollection: [],
|
|
672
|
+
canArchiveCollection: [],
|
|
673
|
+
canUpdateStandards: [],
|
|
674
|
+
canUpdateCustomData: [],
|
|
675
|
+
canUpdateManager: [],
|
|
676
|
+
canUpdateCollectionMetadata: [],
|
|
677
|
+
canUpdateValidTokenIds: [],
|
|
678
|
+
canUpdateTokenMetadata: [],
|
|
679
|
+
canUpdateCollectionApprovals: [],
|
|
680
|
+
canAddMoreAliasPaths: [],
|
|
681
|
+
canAddMoreCosmosCoinWrapperPaths: []
|
|
682
|
+
});
|
|
683
|
+
const err = CollectionPermissionsWithDetails.validateUpdate(makeEmpty(), makeEmpty());
|
|
684
|
+
expect(err).toBeNull();
|
|
685
|
+
});
|
|
686
|
+
});
|
|
687
|
+
});
|
|
688
|
+
describe('UserOutgoingApprovalPermission', () => {
|
|
689
|
+
const makeOutgoing = (permitted = [], forbidden = []) => new UserOutgoingApprovalPermission({
|
|
690
|
+
toListId: 'All',
|
|
691
|
+
initiatedByListId: 'All',
|
|
692
|
+
approvalId: 'All',
|
|
693
|
+
transferTimes: [{ start: 1n, end: 18446744073709551615n }],
|
|
694
|
+
tokenIds: [{ start: 1n, end: 18446744073709551615n }],
|
|
695
|
+
ownershipTimes: [{ start: 1n, end: 18446744073709551615n }],
|
|
696
|
+
permanentlyPermittedTimes: permitted.map(([s, e]) => ({ start: s, end: e })),
|
|
697
|
+
permanentlyForbiddenTimes: forbidden.map(([s, e]) => ({ start: s, end: e }))
|
|
698
|
+
});
|
|
699
|
+
describe('construction', () => {
|
|
700
|
+
it('should create with all required fields', () => {
|
|
701
|
+
const perm = makeOutgoing([[1n, 100n]]);
|
|
702
|
+
expect(perm).toBeTruthy();
|
|
703
|
+
expect(perm.toListId).toBe('All');
|
|
704
|
+
expect(perm.initiatedByListId).toBe('All');
|
|
705
|
+
expect(perm.approvalId).toBe('All');
|
|
706
|
+
expect(perm.transferTimes.length).toBe(1);
|
|
707
|
+
expect(perm.tokenIds.length).toBe(1);
|
|
708
|
+
expect(perm.ownershipTimes.length).toBe(1);
|
|
709
|
+
expect(perm.permanentlyPermittedTimes.length).toBe(1);
|
|
710
|
+
});
|
|
711
|
+
});
|
|
712
|
+
describe('convert', () => {
|
|
713
|
+
it('should convert number type to string', () => {
|
|
714
|
+
const perm = makeOutgoing([[1n, 50n]]);
|
|
715
|
+
const stringified = perm.convert(Stringify);
|
|
716
|
+
expect(stringified.tokenIds[0].start).toBe('1');
|
|
717
|
+
expect(stringified.tokenIds[0].end).toBe('18446744073709551615');
|
|
718
|
+
expect(stringified.permanentlyPermittedTimes[0].start).toBe('1');
|
|
719
|
+
expect(stringified.permanentlyPermittedTimes[0].end).toBe('50');
|
|
720
|
+
});
|
|
721
|
+
});
|
|
722
|
+
describe('toProto / fromProto', () => {
|
|
723
|
+
it('should round-trip through proto', () => {
|
|
724
|
+
const perm = makeOutgoing([[10n, 200n]]);
|
|
725
|
+
const proto = perm.toProto();
|
|
726
|
+
expect(proto).toBeTruthy();
|
|
727
|
+
const restored = UserOutgoingApprovalPermission.fromProto(proto, BigIntify);
|
|
728
|
+
expect(restored.toListId).toBe('All');
|
|
729
|
+
expect(restored.permanentlyPermittedTimes[0].start).toBe(10n);
|
|
730
|
+
expect(restored.permanentlyPermittedTimes[0].end).toBe(200n);
|
|
731
|
+
});
|
|
732
|
+
});
|
|
733
|
+
describe('fromJson / fromJsonString', () => {
|
|
734
|
+
it('should round-trip through JSON', () => {
|
|
735
|
+
const perm = makeOutgoing([[5n, 50n]]);
|
|
736
|
+
const jsonVal = perm.toProto().toJson();
|
|
737
|
+
const restored = UserOutgoingApprovalPermission.fromJson(jsonVal, BigIntify);
|
|
738
|
+
expect(restored.permanentlyPermittedTimes[0].start).toBe(5n);
|
|
739
|
+
});
|
|
740
|
+
it('should round-trip through JSON string', () => {
|
|
741
|
+
const perm = makeOutgoing([], [[1n, 100n]]);
|
|
742
|
+
const jsonStr = perm.toProto().toJsonString();
|
|
743
|
+
const restored = UserOutgoingApprovalPermission.fromJsonString(jsonStr, BigIntify);
|
|
744
|
+
expect(restored.permanentlyForbiddenTimes[0].start).toBe(1n);
|
|
745
|
+
expect(restored.permanentlyForbiddenTimes[0].end).toBe(100n);
|
|
746
|
+
});
|
|
747
|
+
});
|
|
748
|
+
describe('castToCollectionApprovalPermission', () => {
|
|
749
|
+
it('should cast to CollectionApprovalPermission with given fromListId', () => {
|
|
750
|
+
const perm = makeOutgoing([[1n, 100n]]);
|
|
751
|
+
const addr = genTestAddress();
|
|
752
|
+
const casted = perm.castToCollectionApprovalPermission(addr);
|
|
753
|
+
expect(casted.fromListId).toBe(addr);
|
|
754
|
+
});
|
|
755
|
+
});
|
|
756
|
+
describe('toBech32Addresses', () => {
|
|
757
|
+
it('should convert listIds to bech32', () => {
|
|
758
|
+
const perm = makeOutgoing();
|
|
759
|
+
expect(() => perm.toBech32Addresses('bb')).not.toThrow();
|
|
760
|
+
});
|
|
761
|
+
});
|
|
762
|
+
describe('validateUpdate', () => {
|
|
763
|
+
it('should allow identical outgoing permissions', () => {
|
|
764
|
+
const makeWithDetails = (permitted) => new UserOutgoingApprovalPermissionWithDetails({
|
|
765
|
+
toListId: 'All',
|
|
766
|
+
initiatedByListId: 'All',
|
|
767
|
+
approvalId: 'All',
|
|
768
|
+
transferTimes: [{ start: 1n, end: 18446744073709551615n }],
|
|
769
|
+
tokenIds: [{ start: 1n, end: 18446744073709551615n }],
|
|
770
|
+
ownershipTimes: [{ start: 1n, end: 18446744073709551615n }],
|
|
771
|
+
permanentlyPermittedTimes: permitted.map(([s, e]) => ({ start: s, end: e })),
|
|
772
|
+
permanentlyForbiddenTimes: [],
|
|
773
|
+
toList: allAddresses(),
|
|
774
|
+
initiatedByList: allAddresses()
|
|
775
|
+
});
|
|
776
|
+
const perms = [makeWithDetails([[1n, 100n]])];
|
|
777
|
+
const err = UserOutgoingApprovalPermission.validateUpdate(perms, perms);
|
|
778
|
+
expect(err).toBeNull();
|
|
779
|
+
});
|
|
780
|
+
it('should reject removing outgoing permission', () => {
|
|
781
|
+
const makeWithDetails = () => new UserOutgoingApprovalPermissionWithDetails({
|
|
782
|
+
toListId: 'All',
|
|
783
|
+
initiatedByListId: 'All',
|
|
784
|
+
approvalId: 'All',
|
|
785
|
+
transferTimes: [{ start: 1n, end: 18446744073709551615n }],
|
|
786
|
+
tokenIds: [{ start: 1n, end: 18446744073709551615n }],
|
|
787
|
+
ownershipTimes: [{ start: 1n, end: 18446744073709551615n }],
|
|
788
|
+
permanentlyPermittedTimes: [{ start: 1n, end: 100n }],
|
|
789
|
+
permanentlyForbiddenTimes: [],
|
|
790
|
+
toList: allAddresses(),
|
|
791
|
+
initiatedByList: allAddresses()
|
|
792
|
+
});
|
|
793
|
+
const err = UserOutgoingApprovalPermission.validateUpdate([makeWithDetails()], []);
|
|
794
|
+
expect(err).not.toBeNull();
|
|
795
|
+
});
|
|
796
|
+
});
|
|
797
|
+
describe('check', () => {
|
|
798
|
+
it('should return null when outgoing approval is permitted', () => {
|
|
799
|
+
const perm = new UserOutgoingApprovalPermissionWithDetails({
|
|
800
|
+
toListId: 'All',
|
|
801
|
+
initiatedByListId: 'All',
|
|
802
|
+
approvalId: 'All',
|
|
803
|
+
transferTimes: [{ start: 1n, end: 18446744073709551615n }],
|
|
804
|
+
tokenIds: [{ start: 1n, end: 18446744073709551615n }],
|
|
805
|
+
ownershipTimes: [{ start: 1n, end: 18446744073709551615n }],
|
|
806
|
+
permanentlyPermittedTimes: [{ start: 1n, end: 18446744073709551615n }],
|
|
807
|
+
permanentlyForbiddenTimes: [],
|
|
808
|
+
toList: allAddresses(),
|
|
809
|
+
initiatedByList: allAddresses()
|
|
810
|
+
});
|
|
811
|
+
const err = UserOutgoingApprovalPermission.check([
|
|
812
|
+
{
|
|
813
|
+
tokenIds: UintRangeArray.From([{ start: 1n, end: 5n }]),
|
|
814
|
+
ownershipTimes: fullRange(),
|
|
815
|
+
transferTimes: fullRange(),
|
|
816
|
+
toList: allAddresses(),
|
|
817
|
+
fromList: allAddresses(),
|
|
818
|
+
initiatedByList: allAddresses(),
|
|
819
|
+
approvalIdList: allAddresses(),
|
|
820
|
+
amountTrackerIdList: allAddresses(),
|
|
821
|
+
challengeTrackerIdList: allAddresses()
|
|
822
|
+
}
|
|
823
|
+
], [perm], 50n);
|
|
824
|
+
expect(err).toBeNull();
|
|
825
|
+
});
|
|
826
|
+
it('should return error when outgoing approval is forbidden', () => {
|
|
827
|
+
const perm = new UserOutgoingApprovalPermissionWithDetails({
|
|
828
|
+
toListId: 'All',
|
|
829
|
+
initiatedByListId: 'All',
|
|
830
|
+
approvalId: 'All',
|
|
831
|
+
transferTimes: [{ start: 1n, end: 18446744073709551615n }],
|
|
832
|
+
tokenIds: [{ start: 1n, end: 18446744073709551615n }],
|
|
833
|
+
ownershipTimes: [{ start: 1n, end: 18446744073709551615n }],
|
|
834
|
+
permanentlyPermittedTimes: [],
|
|
835
|
+
permanentlyForbiddenTimes: [{ start: 1n, end: 18446744073709551615n }],
|
|
836
|
+
toList: allAddresses(),
|
|
837
|
+
initiatedByList: allAddresses()
|
|
838
|
+
});
|
|
839
|
+
const err = UserOutgoingApprovalPermission.check([
|
|
840
|
+
{
|
|
841
|
+
tokenIds: UintRangeArray.From([{ start: 1n, end: 5n }]),
|
|
842
|
+
ownershipTimes: fullRange(),
|
|
843
|
+
transferTimes: fullRange(),
|
|
844
|
+
toList: allAddresses(),
|
|
845
|
+
fromList: allAddresses(),
|
|
846
|
+
initiatedByList: allAddresses(),
|
|
847
|
+
approvalIdList: allAddresses(),
|
|
848
|
+
amountTrackerIdList: allAddresses(),
|
|
849
|
+
challengeTrackerIdList: allAddresses()
|
|
850
|
+
}
|
|
851
|
+
], [perm], 50n);
|
|
852
|
+
expect(err).not.toBeNull();
|
|
853
|
+
});
|
|
854
|
+
});
|
|
855
|
+
});
|
|
856
|
+
describe('UserIncomingApprovalPermission', () => {
|
|
857
|
+
const makeIncoming = (permitted = [], forbidden = []) => new UserIncomingApprovalPermission({
|
|
858
|
+
fromListId: 'All',
|
|
859
|
+
initiatedByListId: 'All',
|
|
860
|
+
approvalId: 'All',
|
|
861
|
+
transferTimes: [{ start: 1n, end: 18446744073709551615n }],
|
|
862
|
+
tokenIds: [{ start: 1n, end: 18446744073709551615n }],
|
|
863
|
+
ownershipTimes: [{ start: 1n, end: 18446744073709551615n }],
|
|
864
|
+
permanentlyPermittedTimes: permitted.map(([s, e]) => ({ start: s, end: e })),
|
|
865
|
+
permanentlyForbiddenTimes: forbidden.map(([s, e]) => ({ start: s, end: e }))
|
|
866
|
+
});
|
|
867
|
+
describe('construction', () => {
|
|
868
|
+
it('should create with all required fields', () => {
|
|
869
|
+
const perm = makeIncoming([[1n, 100n]]);
|
|
870
|
+
expect(perm).toBeTruthy();
|
|
871
|
+
expect(perm.fromListId).toBe('All');
|
|
872
|
+
expect(perm.initiatedByListId).toBe('All');
|
|
873
|
+
expect(perm.approvalId).toBe('All');
|
|
874
|
+
expect(perm.permanentlyPermittedTimes.length).toBe(1);
|
|
875
|
+
});
|
|
876
|
+
});
|
|
877
|
+
describe('convert', () => {
|
|
878
|
+
it('should convert to string type', () => {
|
|
879
|
+
const perm = makeIncoming([[1n, 50n]]);
|
|
880
|
+
const stringified = perm.convert(Stringify);
|
|
881
|
+
expect(stringified.tokenIds[0].start).toBe('1');
|
|
882
|
+
expect(stringified.permanentlyPermittedTimes[0].end).toBe('50');
|
|
883
|
+
});
|
|
884
|
+
});
|
|
885
|
+
describe('toProto / fromProto', () => {
|
|
886
|
+
it('should round-trip through proto', () => {
|
|
887
|
+
const perm = makeIncoming([[10n, 200n]]);
|
|
888
|
+
const proto = perm.toProto();
|
|
889
|
+
const restored = UserIncomingApprovalPermission.fromProto(proto, BigIntify);
|
|
890
|
+
expect(restored.fromListId).toBe('All');
|
|
891
|
+
expect(restored.permanentlyPermittedTimes[0].start).toBe(10n);
|
|
892
|
+
});
|
|
893
|
+
});
|
|
894
|
+
describe('fromJson / fromJsonString', () => {
|
|
895
|
+
it('should round-trip through JSON', () => {
|
|
896
|
+
const perm = makeIncoming([[5n, 50n]]);
|
|
897
|
+
const jsonVal = perm.toProto().toJson();
|
|
898
|
+
const restored = UserIncomingApprovalPermission.fromJson(jsonVal, BigIntify);
|
|
899
|
+
expect(restored.permanentlyPermittedTimes[0].start).toBe(5n);
|
|
900
|
+
});
|
|
901
|
+
it('should round-trip through JSON string', () => {
|
|
902
|
+
const perm = makeIncoming([], [[1n, 100n]]);
|
|
903
|
+
const jsonStr = perm.toProto().toJsonString();
|
|
904
|
+
const restored = UserIncomingApprovalPermission.fromJsonString(jsonStr, BigIntify);
|
|
905
|
+
expect(restored.permanentlyForbiddenTimes[0].start).toBe(1n);
|
|
906
|
+
});
|
|
907
|
+
});
|
|
908
|
+
describe('castToCollectionApprovalPermission', () => {
|
|
909
|
+
it('should cast to CollectionApprovalPermission with given toListId', () => {
|
|
910
|
+
const perm = makeIncoming([[1n, 100n]]);
|
|
911
|
+
const addr = genTestAddress();
|
|
912
|
+
const casted = perm.castToCollectionApprovalPermission(addr);
|
|
913
|
+
expect(casted.toListId).toBe(addr);
|
|
914
|
+
});
|
|
915
|
+
});
|
|
916
|
+
describe('toBech32Addresses', () => {
|
|
917
|
+
it('should not throw when converting reserved list IDs', () => {
|
|
918
|
+
const perm = makeIncoming();
|
|
919
|
+
expect(() => perm.toBech32Addresses('bb')).not.toThrow();
|
|
920
|
+
});
|
|
921
|
+
});
|
|
922
|
+
describe('validateUpdate', () => {
|
|
923
|
+
it('should allow identical incoming permissions', () => {
|
|
924
|
+
const makeWithDetails = () => new UserIncomingApprovalPermissionWithDetails({
|
|
925
|
+
fromListId: 'All',
|
|
926
|
+
initiatedByListId: 'All',
|
|
927
|
+
approvalId: 'All',
|
|
928
|
+
transferTimes: [{ start: 1n, end: 18446744073709551615n }],
|
|
929
|
+
tokenIds: [{ start: 1n, end: 18446744073709551615n }],
|
|
930
|
+
ownershipTimes: [{ start: 1n, end: 18446744073709551615n }],
|
|
931
|
+
permanentlyPermittedTimes: [{ start: 1n, end: 100n }],
|
|
932
|
+
permanentlyForbiddenTimes: [],
|
|
933
|
+
fromList: allAddresses(),
|
|
934
|
+
initiatedByList: allAddresses()
|
|
935
|
+
});
|
|
936
|
+
const perms = [makeWithDetails()];
|
|
937
|
+
const err = UserIncomingApprovalPermission.validateUpdate(perms, perms);
|
|
938
|
+
expect(err).toBeNull();
|
|
939
|
+
});
|
|
940
|
+
it('should reject removing incoming permission', () => {
|
|
941
|
+
const makeWithDetails = () => new UserIncomingApprovalPermissionWithDetails({
|
|
942
|
+
fromListId: 'All',
|
|
943
|
+
initiatedByListId: 'All',
|
|
944
|
+
approvalId: 'All',
|
|
945
|
+
transferTimes: [{ start: 1n, end: 18446744073709551615n }],
|
|
946
|
+
tokenIds: [{ start: 1n, end: 18446744073709551615n }],
|
|
947
|
+
ownershipTimes: [{ start: 1n, end: 18446744073709551615n }],
|
|
948
|
+
permanentlyPermittedTimes: [{ start: 1n, end: 100n }],
|
|
949
|
+
permanentlyForbiddenTimes: [],
|
|
950
|
+
fromList: allAddresses(),
|
|
951
|
+
initiatedByList: allAddresses()
|
|
952
|
+
});
|
|
953
|
+
const err = UserIncomingApprovalPermission.validateUpdate([makeWithDetails()], []);
|
|
954
|
+
expect(err).not.toBeNull();
|
|
955
|
+
});
|
|
956
|
+
});
|
|
957
|
+
describe('check', () => {
|
|
958
|
+
it('should return null when incoming approval is permitted', () => {
|
|
959
|
+
const perm = new UserIncomingApprovalPermissionWithDetails({
|
|
960
|
+
fromListId: 'All',
|
|
961
|
+
initiatedByListId: 'All',
|
|
962
|
+
approvalId: 'All',
|
|
963
|
+
transferTimes: [{ start: 1n, end: 18446744073709551615n }],
|
|
964
|
+
tokenIds: [{ start: 1n, end: 18446744073709551615n }],
|
|
965
|
+
ownershipTimes: [{ start: 1n, end: 18446744073709551615n }],
|
|
966
|
+
permanentlyPermittedTimes: [{ start: 1n, end: 18446744073709551615n }],
|
|
967
|
+
permanentlyForbiddenTimes: [],
|
|
968
|
+
fromList: allAddresses(),
|
|
969
|
+
initiatedByList: allAddresses()
|
|
970
|
+
});
|
|
971
|
+
const err = UserIncomingApprovalPermission.check([
|
|
972
|
+
{
|
|
973
|
+
tokenIds: fullRange(),
|
|
974
|
+
ownershipTimes: fullRange(),
|
|
975
|
+
transferTimes: fullRange(),
|
|
976
|
+
toList: allAddresses(),
|
|
977
|
+
fromList: allAddresses(),
|
|
978
|
+
initiatedByList: allAddresses(),
|
|
979
|
+
approvalIdList: allAddresses(),
|
|
980
|
+
amountTrackerIdList: allAddresses(),
|
|
981
|
+
challengeTrackerIdList: allAddresses()
|
|
982
|
+
}
|
|
983
|
+
], [perm], 50n);
|
|
984
|
+
expect(err).toBeNull();
|
|
985
|
+
});
|
|
986
|
+
it('should return error when incoming approval is forbidden', () => {
|
|
987
|
+
const perm = new UserIncomingApprovalPermissionWithDetails({
|
|
988
|
+
fromListId: 'All',
|
|
989
|
+
initiatedByListId: 'All',
|
|
990
|
+
approvalId: 'All',
|
|
991
|
+
transferTimes: [{ start: 1n, end: 18446744073709551615n }],
|
|
992
|
+
tokenIds: [{ start: 1n, end: 18446744073709551615n }],
|
|
993
|
+
ownershipTimes: [{ start: 1n, end: 18446744073709551615n }],
|
|
994
|
+
permanentlyPermittedTimes: [],
|
|
995
|
+
permanentlyForbiddenTimes: [{ start: 1n, end: 18446744073709551615n }],
|
|
996
|
+
fromList: allAddresses(),
|
|
997
|
+
initiatedByList: allAddresses()
|
|
998
|
+
});
|
|
999
|
+
const err = UserIncomingApprovalPermission.check([
|
|
1000
|
+
{
|
|
1001
|
+
tokenIds: fullRange(),
|
|
1002
|
+
ownershipTimes: fullRange(),
|
|
1003
|
+
transferTimes: fullRange(),
|
|
1004
|
+
toList: allAddresses(),
|
|
1005
|
+
fromList: allAddresses(),
|
|
1006
|
+
initiatedByList: allAddresses(),
|
|
1007
|
+
approvalIdList: allAddresses(),
|
|
1008
|
+
amountTrackerIdList: allAddresses(),
|
|
1009
|
+
challengeTrackerIdList: allAddresses()
|
|
1010
|
+
}
|
|
1011
|
+
], [perm], 50n);
|
|
1012
|
+
expect(err).not.toBeNull();
|
|
1013
|
+
});
|
|
1014
|
+
});
|
|
1015
|
+
});
|
|
1016
|
+
describe('CollectionPermissions - serialization', () => {
|
|
1017
|
+
const makeEmpty = () => CollectionPermissions.InitEmpty();
|
|
1018
|
+
describe('convert', () => {
|
|
1019
|
+
it('should convert all fields when they contain data (covers map bodies in convert)', () => {
|
|
1020
|
+
const perms = new CollectionPermissions({
|
|
1021
|
+
canDeleteCollection: [new ActionPermission({ permanentlyPermittedTimes: [{ start: 1n, end: 50n }], permanentlyForbiddenTimes: [] })],
|
|
1022
|
+
canArchiveCollection: [new ActionPermission({ permanentlyPermittedTimes: [{ start: 2n, end: 3n }], permanentlyForbiddenTimes: [] })],
|
|
1023
|
+
canUpdateStandards: [new ActionPermission({ permanentlyPermittedTimes: [{ start: 4n, end: 5n }], permanentlyForbiddenTimes: [] })],
|
|
1024
|
+
canUpdateCustomData: [new ActionPermission({ permanentlyPermittedTimes: [{ start: 6n, end: 7n }], permanentlyForbiddenTimes: [] })],
|
|
1025
|
+
canUpdateManager: [new ActionPermission({ permanentlyPermittedTimes: [{ start: 8n, end: 9n }], permanentlyForbiddenTimes: [] })],
|
|
1026
|
+
canUpdateCollectionMetadata: [new ActionPermission({ permanentlyPermittedTimes: [{ start: 10n, end: 11n }], permanentlyForbiddenTimes: [] })],
|
|
1027
|
+
canUpdateValidTokenIds: [new TokenIdsActionPermission({ tokenIds: [{ start: 1n, end: 5n }], permanentlyPermittedTimes: [{ start: 1n, end: 10n }], permanentlyForbiddenTimes: [] })],
|
|
1028
|
+
canUpdateTokenMetadata: [new TokenIdsActionPermission({ tokenIds: [{ start: 6n, end: 10n }], permanentlyPermittedTimes: [], permanentlyForbiddenTimes: [{ start: 1n, end: 100n }] })],
|
|
1029
|
+
canUpdateCollectionApprovals: [],
|
|
1030
|
+
canAddMoreAliasPaths: [new ActionPermission({ permanentlyPermittedTimes: [{ start: 20n, end: 30n }], permanentlyForbiddenTimes: [] })],
|
|
1031
|
+
canAddMoreCosmosCoinWrapperPaths: [new ActionPermission({ permanentlyPermittedTimes: [{ start: 40n, end: 50n }], permanentlyForbiddenTimes: [] })]
|
|
1032
|
+
});
|
|
1033
|
+
const converted = perms.convert(Stringify);
|
|
1034
|
+
expect(converted.canDeleteCollection[0].permanentlyPermittedTimes[0].start).toBe('1');
|
|
1035
|
+
expect(converted.canArchiveCollection[0].permanentlyPermittedTimes[0].start).toBe('2');
|
|
1036
|
+
expect(converted.canUpdateStandards[0].permanentlyPermittedTimes[0].start).toBe('4');
|
|
1037
|
+
expect(converted.canUpdateCustomData[0].permanentlyPermittedTimes[0].start).toBe('6');
|
|
1038
|
+
expect(converted.canUpdateManager[0].permanentlyPermittedTimes[0].start).toBe('8');
|
|
1039
|
+
expect(converted.canUpdateCollectionMetadata[0].permanentlyPermittedTimes[0].start).toBe('10');
|
|
1040
|
+
expect(converted.canUpdateValidTokenIds[0].tokenIds[0].start).toBe('1');
|
|
1041
|
+
expect(converted.canUpdateTokenMetadata[0].permanentlyForbiddenTimes[0].start).toBe('1');
|
|
1042
|
+
expect(converted.canAddMoreAliasPaths[0].permanentlyPermittedTimes[0].start).toBe('20');
|
|
1043
|
+
expect(converted.canAddMoreCosmosCoinWrapperPaths[0].permanentlyPermittedTimes[0].start).toBe('40');
|
|
1044
|
+
});
|
|
1045
|
+
});
|
|
1046
|
+
describe('toProto / fromProto', () => {
|
|
1047
|
+
it('should round-trip empty permissions through proto', () => {
|
|
1048
|
+
const perms = makeEmpty();
|
|
1049
|
+
const proto = perms.toProto();
|
|
1050
|
+
const restored = CollectionPermissions.fromProto(proto, BigIntify);
|
|
1051
|
+
expect(restored).toBeTruthy();
|
|
1052
|
+
expect(restored.canDeleteCollection.length).toBe(0);
|
|
1053
|
+
expect(restored.canUpdateManager.length).toBe(0);
|
|
1054
|
+
});
|
|
1055
|
+
it('should round-trip permissions with data through proto', () => {
|
|
1056
|
+
const perms = new CollectionPermissions({
|
|
1057
|
+
canDeleteCollection: [
|
|
1058
|
+
new ActionPermission({
|
|
1059
|
+
permanentlyPermittedTimes: [{ start: 1n, end: 100n }],
|
|
1060
|
+
permanentlyForbiddenTimes: []
|
|
1061
|
+
})
|
|
1062
|
+
],
|
|
1063
|
+
canArchiveCollection: [],
|
|
1064
|
+
canUpdateStandards: [],
|
|
1065
|
+
canUpdateCustomData: [],
|
|
1066
|
+
canUpdateManager: [
|
|
1067
|
+
new ActionPermission({
|
|
1068
|
+
permanentlyPermittedTimes: [],
|
|
1069
|
+
permanentlyForbiddenTimes: [{ start: 1n, end: 50n }]
|
|
1070
|
+
})
|
|
1071
|
+
],
|
|
1072
|
+
canUpdateCollectionMetadata: [],
|
|
1073
|
+
canUpdateValidTokenIds: [
|
|
1074
|
+
new TokenIdsActionPermission({
|
|
1075
|
+
tokenIds: [{ start: 1n, end: 10n }],
|
|
1076
|
+
permanentlyPermittedTimes: [{ start: 1n, end: 100n }],
|
|
1077
|
+
permanentlyForbiddenTimes: []
|
|
1078
|
+
})
|
|
1079
|
+
],
|
|
1080
|
+
canUpdateTokenMetadata: [],
|
|
1081
|
+
canUpdateCollectionApprovals: [],
|
|
1082
|
+
canAddMoreAliasPaths: [],
|
|
1083
|
+
canAddMoreCosmosCoinWrapperPaths: []
|
|
1084
|
+
});
|
|
1085
|
+
const proto = perms.toProto();
|
|
1086
|
+
const restored = CollectionPermissions.fromProto(proto, BigIntify);
|
|
1087
|
+
expect(restored.canDeleteCollection.length).toBe(1);
|
|
1088
|
+
expect(restored.canDeleteCollection[0].permanentlyPermittedTimes[0].start).toBe(1n);
|
|
1089
|
+
expect(restored.canDeleteCollection[0].permanentlyPermittedTimes[0].end).toBe(100n);
|
|
1090
|
+
expect(restored.canUpdateManager.length).toBe(1);
|
|
1091
|
+
expect(restored.canUpdateManager[0].permanentlyForbiddenTimes[0].start).toBe(1n);
|
|
1092
|
+
expect(restored.canUpdateValidTokenIds.length).toBe(1);
|
|
1093
|
+
expect(restored.canUpdateValidTokenIds[0].tokenIds[0].start).toBe(1n);
|
|
1094
|
+
});
|
|
1095
|
+
});
|
|
1096
|
+
describe('fromJson / fromJsonString', () => {
|
|
1097
|
+
it('should round-trip through JSON', () => {
|
|
1098
|
+
const perms = new CollectionPermissions({
|
|
1099
|
+
canDeleteCollection: [
|
|
1100
|
+
new ActionPermission({
|
|
1101
|
+
permanentlyPermittedTimes: [{ start: 10n, end: 20n }],
|
|
1102
|
+
permanentlyForbiddenTimes: []
|
|
1103
|
+
})
|
|
1104
|
+
],
|
|
1105
|
+
canArchiveCollection: [],
|
|
1106
|
+
canUpdateStandards: [],
|
|
1107
|
+
canUpdateCustomData: [],
|
|
1108
|
+
canUpdateManager: [],
|
|
1109
|
+
canUpdateCollectionMetadata: [],
|
|
1110
|
+
canUpdateValidTokenIds: [],
|
|
1111
|
+
canUpdateTokenMetadata: [],
|
|
1112
|
+
canUpdateCollectionApprovals: [],
|
|
1113
|
+
canAddMoreAliasPaths: [],
|
|
1114
|
+
canAddMoreCosmosCoinWrapperPaths: []
|
|
1115
|
+
});
|
|
1116
|
+
const jsonVal = perms.toProto().toJson();
|
|
1117
|
+
const restored = CollectionPermissions.fromJson(jsonVal, BigIntify);
|
|
1118
|
+
expect(restored.canDeleteCollection[0].permanentlyPermittedTimes[0].start).toBe(10n);
|
|
1119
|
+
});
|
|
1120
|
+
it('should round-trip through JSON string', () => {
|
|
1121
|
+
const perms = makeEmpty();
|
|
1122
|
+
const jsonStr = perms.toProto().toJsonString();
|
|
1123
|
+
const restored = CollectionPermissions.fromJsonString(jsonStr, BigIntify);
|
|
1124
|
+
expect(restored.canDeleteCollection.length).toBe(0);
|
|
1125
|
+
});
|
|
1126
|
+
});
|
|
1127
|
+
describe('toBech32Addresses', () => {
|
|
1128
|
+
it('should run without throwing for empty permissions', () => {
|
|
1129
|
+
const perms = makeEmpty();
|
|
1130
|
+
expect(() => perms.toBech32Addresses('bb')).not.toThrow();
|
|
1131
|
+
});
|
|
1132
|
+
it('should convert collection approval permission addresses', () => {
|
|
1133
|
+
const perms = new CollectionPermissions({
|
|
1134
|
+
canDeleteCollection: [],
|
|
1135
|
+
canArchiveCollection: [],
|
|
1136
|
+
canUpdateStandards: [],
|
|
1137
|
+
canUpdateCustomData: [],
|
|
1138
|
+
canUpdateManager: [],
|
|
1139
|
+
canUpdateCollectionMetadata: [],
|
|
1140
|
+
canUpdateValidTokenIds: [],
|
|
1141
|
+
canUpdateTokenMetadata: [],
|
|
1142
|
+
canUpdateCollectionApprovals: [
|
|
1143
|
+
new CollectionApprovalPermission({
|
|
1144
|
+
fromListId: 'All',
|
|
1145
|
+
toListId: 'All',
|
|
1146
|
+
initiatedByListId: 'All',
|
|
1147
|
+
approvalId: 'All',
|
|
1148
|
+
transferTimes: [{ start: 1n, end: 18446744073709551615n }],
|
|
1149
|
+
tokenIds: [{ start: 1n, end: 18446744073709551615n }],
|
|
1150
|
+
ownershipTimes: [{ start: 1n, end: 18446744073709551615n }],
|
|
1151
|
+
permanentlyPermittedTimes: [],
|
|
1152
|
+
permanentlyForbiddenTimes: []
|
|
1153
|
+
})
|
|
1154
|
+
],
|
|
1155
|
+
canAddMoreAliasPaths: [],
|
|
1156
|
+
canAddMoreCosmosCoinWrapperPaths: []
|
|
1157
|
+
});
|
|
1158
|
+
expect(() => perms.toBech32Addresses('bb')).not.toThrow();
|
|
1159
|
+
});
|
|
1160
|
+
});
|
|
1161
|
+
describe('validateUpdate - more permission types', () => {
|
|
1162
|
+
const makePerms = (opts) => new CollectionPermissionsWithDetails({
|
|
1163
|
+
canDeleteCollection: [],
|
|
1164
|
+
canArchiveCollection: [],
|
|
1165
|
+
canUpdateStandards: [],
|
|
1166
|
+
canUpdateCustomData: [],
|
|
1167
|
+
canUpdateManager: [],
|
|
1168
|
+
canUpdateCollectionMetadata: [],
|
|
1169
|
+
canUpdateValidTokenIds: opts.canUpdateValidTokenIds || [],
|
|
1170
|
+
canUpdateTokenMetadata: [],
|
|
1171
|
+
canUpdateCollectionApprovals: opts.canUpdateCollectionApprovals || [],
|
|
1172
|
+
canAddMoreAliasPaths: [],
|
|
1173
|
+
canAddMoreCosmosCoinWrapperPaths: []
|
|
1174
|
+
});
|
|
1175
|
+
it('should reject removing canUpdateValidTokenIds permission', () => {
|
|
1176
|
+
const oldPerms = makePerms({
|
|
1177
|
+
canUpdateValidTokenIds: [
|
|
1178
|
+
new TokenIdsActionPermission({
|
|
1179
|
+
tokenIds: [{ start: 1n, end: 10n }],
|
|
1180
|
+
permanentlyPermittedTimes: [{ start: 1n, end: 100n }],
|
|
1181
|
+
permanentlyForbiddenTimes: []
|
|
1182
|
+
})
|
|
1183
|
+
]
|
|
1184
|
+
});
|
|
1185
|
+
const newPerms = makePerms({});
|
|
1186
|
+
const err = CollectionPermissionsWithDetails.validateUpdate(oldPerms, newPerms);
|
|
1187
|
+
expect(err).not.toBeNull();
|
|
1188
|
+
});
|
|
1189
|
+
it('should allow adding canUpdateValidTokenIds when previously empty', () => {
|
|
1190
|
+
const oldPerms = makePerms({});
|
|
1191
|
+
const newPerms = makePerms({
|
|
1192
|
+
canUpdateValidTokenIds: [
|
|
1193
|
+
new TokenIdsActionPermission({
|
|
1194
|
+
tokenIds: [{ start: 1n, end: 10n }],
|
|
1195
|
+
permanentlyPermittedTimes: [{ start: 1n, end: 100n }],
|
|
1196
|
+
permanentlyForbiddenTimes: []
|
|
1197
|
+
})
|
|
1198
|
+
]
|
|
1199
|
+
});
|
|
1200
|
+
const err = CollectionPermissionsWithDetails.validateUpdate(oldPerms, newPerms);
|
|
1201
|
+
expect(err).toBeNull();
|
|
1202
|
+
});
|
|
1203
|
+
});
|
|
1204
|
+
});
|
|
1205
|
+
describe('CollectionApprovalPermission - serialization', () => {
|
|
1206
|
+
const makeApprovalBase = (permitted = [], forbidden = []) => new CollectionApprovalPermission({
|
|
1207
|
+
fromListId: 'All',
|
|
1208
|
+
toListId: 'All',
|
|
1209
|
+
initiatedByListId: 'All',
|
|
1210
|
+
approvalId: 'All',
|
|
1211
|
+
transferTimes: [{ start: 1n, end: 18446744073709551615n }],
|
|
1212
|
+
tokenIds: [{ start: 1n, end: 18446744073709551615n }],
|
|
1213
|
+
ownershipTimes: [{ start: 1n, end: 18446744073709551615n }],
|
|
1214
|
+
permanentlyPermittedTimes: permitted.map(([s, e]) => ({ start: s, end: e })),
|
|
1215
|
+
permanentlyForbiddenTimes: forbidden.map(([s, e]) => ({ start: s, end: e }))
|
|
1216
|
+
});
|
|
1217
|
+
it('should round-trip through proto', () => {
|
|
1218
|
+
const perm = makeApprovalBase([[10n, 50n]]);
|
|
1219
|
+
const proto = perm.toProto();
|
|
1220
|
+
const restored = CollectionApprovalPermission.fromProto(proto, BigIntify);
|
|
1221
|
+
expect(restored.fromListId).toBe('All');
|
|
1222
|
+
expect(restored.permanentlyPermittedTimes[0].start).toBe(10n);
|
|
1223
|
+
expect(restored.permanentlyPermittedTimes[0].end).toBe(50n);
|
|
1224
|
+
});
|
|
1225
|
+
it('should round-trip through JSON', () => {
|
|
1226
|
+
const perm = makeApprovalBase([[5n, 100n]]);
|
|
1227
|
+
const jsonVal = perm.toProto().toJson();
|
|
1228
|
+
const restored = CollectionApprovalPermission.fromJson(jsonVal, BigIntify);
|
|
1229
|
+
expect(restored.permanentlyPermittedTimes[0].start).toBe(5n);
|
|
1230
|
+
});
|
|
1231
|
+
it('should round-trip through JSON string', () => {
|
|
1232
|
+
const perm = makeApprovalBase([], [[1n, 200n]]);
|
|
1233
|
+
const jsonStr = perm.toProto().toJsonString();
|
|
1234
|
+
const restored = CollectionApprovalPermission.fromJsonString(jsonStr, BigIntify);
|
|
1235
|
+
expect(restored.permanentlyForbiddenTimes[0].start).toBe(1n);
|
|
1236
|
+
expect(restored.permanentlyForbiddenTimes[0].end).toBe(200n);
|
|
1237
|
+
});
|
|
1238
|
+
it('should toBech32Addresses without throwing', () => {
|
|
1239
|
+
const perm = makeApprovalBase();
|
|
1240
|
+
expect(() => perm.toBech32Addresses('bb')).not.toThrow();
|
|
1241
|
+
});
|
|
1242
|
+
});
|
|
1243
|
+
describe('TokenIdsActionPermission - serialization', () => {
|
|
1244
|
+
const makePerm = (permitted = [], forbidden = []) => new TokenIdsActionPermission({
|
|
1245
|
+
tokenIds: [{ start: 1n, end: 100n }],
|
|
1246
|
+
permanentlyPermittedTimes: permitted.map(([s, e]) => ({ start: s, end: e })),
|
|
1247
|
+
permanentlyForbiddenTimes: forbidden.map(([s, e]) => ({ start: s, end: e }))
|
|
1248
|
+
});
|
|
1249
|
+
it('should round-trip through proto', () => {
|
|
1250
|
+
const perm = makePerm([[1n, 50n]]);
|
|
1251
|
+
const proto = perm.toProto();
|
|
1252
|
+
const restored = TokenIdsActionPermission.fromProto(proto, BigIntify);
|
|
1253
|
+
expect(restored.tokenIds[0].start).toBe(1n);
|
|
1254
|
+
expect(restored.tokenIds[0].end).toBe(100n);
|
|
1255
|
+
expect(restored.permanentlyPermittedTimes[0].start).toBe(1n);
|
|
1256
|
+
expect(restored.permanentlyPermittedTimes[0].end).toBe(50n);
|
|
1257
|
+
});
|
|
1258
|
+
it('should round-trip through JSON', () => {
|
|
1259
|
+
const perm = makePerm([[5n, 80n]]);
|
|
1260
|
+
const jsonVal = perm.toProto().toJson();
|
|
1261
|
+
const restored = TokenIdsActionPermission.fromJson(jsonVal, BigIntify);
|
|
1262
|
+
expect(restored.permanentlyPermittedTimes[0].end).toBe(80n);
|
|
1263
|
+
});
|
|
1264
|
+
it('should round-trip through JSON string', () => {
|
|
1265
|
+
const perm = makePerm([], [[10n, 20n]]);
|
|
1266
|
+
const jsonStr = perm.toProto().toJsonString();
|
|
1267
|
+
const restored = TokenIdsActionPermission.fromJsonString(jsonStr, BigIntify);
|
|
1268
|
+
expect(restored.permanentlyForbiddenTimes[0].start).toBe(10n);
|
|
1269
|
+
expect(restored.permanentlyForbiddenTimes[0].end).toBe(20n);
|
|
1270
|
+
});
|
|
1271
|
+
});
|
|
1272
|
+
describe('ActionPermission - serialization', () => {
|
|
1273
|
+
it('should round-trip through proto', () => {
|
|
1274
|
+
const perm = new ActionPermission({
|
|
1275
|
+
permanentlyPermittedTimes: [{ start: 1n, end: 100n }],
|
|
1276
|
+
permanentlyForbiddenTimes: [{ start: 200n, end: 300n }]
|
|
1277
|
+
});
|
|
1278
|
+
const proto = perm.toProto();
|
|
1279
|
+
const restored = ActionPermission.fromProto(proto, BigIntify);
|
|
1280
|
+
expect(restored.permanentlyPermittedTimes[0].start).toBe(1n);
|
|
1281
|
+
expect(restored.permanentlyPermittedTimes[0].end).toBe(100n);
|
|
1282
|
+
expect(restored.permanentlyForbiddenTimes[0].start).toBe(200n);
|
|
1283
|
+
});
|
|
1284
|
+
it('should round-trip through JSON', () => {
|
|
1285
|
+
const perm = new ActionPermission({
|
|
1286
|
+
permanentlyPermittedTimes: [{ start: 5n, end: 50n }],
|
|
1287
|
+
permanentlyForbiddenTimes: []
|
|
1288
|
+
});
|
|
1289
|
+
const jsonVal = perm.toProto().toJson();
|
|
1290
|
+
const restored = ActionPermission.fromJson(jsonVal, BigIntify);
|
|
1291
|
+
expect(restored.permanentlyPermittedTimes[0].start).toBe(5n);
|
|
1292
|
+
});
|
|
1293
|
+
it('should round-trip through JSON string', () => {
|
|
1294
|
+
const perm = new ActionPermission({
|
|
1295
|
+
permanentlyPermittedTimes: [],
|
|
1296
|
+
permanentlyForbiddenTimes: [{ start: 1n, end: 10n }]
|
|
1297
|
+
});
|
|
1298
|
+
const jsonStr = perm.toProto().toJsonString();
|
|
1299
|
+
const restored = ActionPermission.fromJsonString(jsonStr, BigIntify);
|
|
1300
|
+
expect(restored.permanentlyForbiddenTimes[0].end).toBe(10n);
|
|
1301
|
+
});
|
|
1302
|
+
});
|
|
1303
|
+
describe('UserPermissions - serialization', () => {
|
|
1304
|
+
it('should round-trip empty permissions through proto', () => {
|
|
1305
|
+
const perms = UserPermissions.InitEmpty();
|
|
1306
|
+
const proto = perms.toProto();
|
|
1307
|
+
const restored = UserPermissions.fromProto(proto, BigIntify);
|
|
1308
|
+
expect(restored.canUpdateOutgoingApprovals.length).toBe(0);
|
|
1309
|
+
expect(restored.canUpdateIncomingApprovals.length).toBe(0);
|
|
1310
|
+
});
|
|
1311
|
+
it('should round-trip full UserPermissions with actual data through proto (covers fromProto map bodies)', () => {
|
|
1312
|
+
const perms = new UserPermissions({
|
|
1313
|
+
canUpdateOutgoingApprovals: [
|
|
1314
|
+
new UserOutgoingApprovalPermission({
|
|
1315
|
+
toListId: 'All',
|
|
1316
|
+
initiatedByListId: 'All',
|
|
1317
|
+
approvalId: 'All',
|
|
1318
|
+
transferTimes: [{ start: 1n, end: 100n }],
|
|
1319
|
+
tokenIds: [{ start: 1n, end: 10n }],
|
|
1320
|
+
ownershipTimes: [{ start: 1n, end: 100n }],
|
|
1321
|
+
permanentlyPermittedTimes: [{ start: 1n, end: 50n }],
|
|
1322
|
+
permanentlyForbiddenTimes: []
|
|
1323
|
+
})
|
|
1324
|
+
],
|
|
1325
|
+
canUpdateIncomingApprovals: [
|
|
1326
|
+
new UserIncomingApprovalPermission({
|
|
1327
|
+
fromListId: 'All',
|
|
1328
|
+
initiatedByListId: 'All',
|
|
1329
|
+
approvalId: 'All',
|
|
1330
|
+
transferTimes: [{ start: 1n, end: 100n }],
|
|
1331
|
+
tokenIds: [{ start: 1n, end: 10n }],
|
|
1332
|
+
ownershipTimes: [{ start: 1n, end: 100n }],
|
|
1333
|
+
permanentlyPermittedTimes: [],
|
|
1334
|
+
permanentlyForbiddenTimes: [{ start: 1n, end: 50n }]
|
|
1335
|
+
})
|
|
1336
|
+
],
|
|
1337
|
+
canUpdateAutoApproveSelfInitiatedOutgoingTransfers: [
|
|
1338
|
+
new ActionPermission({
|
|
1339
|
+
permanentlyPermittedTimes: [{ start: 1n, end: 100n }],
|
|
1340
|
+
permanentlyForbiddenTimes: []
|
|
1341
|
+
})
|
|
1342
|
+
],
|
|
1343
|
+
canUpdateAutoApproveSelfInitiatedIncomingTransfers: [
|
|
1344
|
+
new ActionPermission({
|
|
1345
|
+
permanentlyPermittedTimes: [],
|
|
1346
|
+
permanentlyForbiddenTimes: [{ start: 1n, end: 10n }]
|
|
1347
|
+
})
|
|
1348
|
+
],
|
|
1349
|
+
canUpdateAutoApproveAllIncomingTransfers: [
|
|
1350
|
+
new ActionPermission({
|
|
1351
|
+
permanentlyPermittedTimes: [{ start: 10n, end: 20n }],
|
|
1352
|
+
permanentlyForbiddenTimes: []
|
|
1353
|
+
})
|
|
1354
|
+
]
|
|
1355
|
+
});
|
|
1356
|
+
const proto = perms.toProto();
|
|
1357
|
+
const restored = UserPermissions.fromProto(proto, BigIntify);
|
|
1358
|
+
expect(restored.canUpdateOutgoingApprovals.length).toBe(1);
|
|
1359
|
+
expect(restored.canUpdateOutgoingApprovals[0].permanentlyPermittedTimes[0].start).toBe(1n);
|
|
1360
|
+
expect(restored.canUpdateIncomingApprovals.length).toBe(1);
|
|
1361
|
+
expect(restored.canUpdateIncomingApprovals[0].permanentlyForbiddenTimes[0].start).toBe(1n);
|
|
1362
|
+
expect(restored.canUpdateAutoApproveSelfInitiatedOutgoingTransfers.length).toBe(1);
|
|
1363
|
+
expect(restored.canUpdateAutoApproveSelfInitiatedOutgoingTransfers[0].permanentlyPermittedTimes[0].end).toBe(100n);
|
|
1364
|
+
expect(restored.canUpdateAutoApproveSelfInitiatedIncomingTransfers.length).toBe(1);
|
|
1365
|
+
expect(restored.canUpdateAutoApproveAllIncomingTransfers.length).toBe(1);
|
|
1366
|
+
expect(restored.canUpdateAutoApproveAllIncomingTransfers[0].permanentlyPermittedTimes[0].start).toBe(10n);
|
|
1367
|
+
});
|
|
1368
|
+
it('should round-trip through JSON', () => {
|
|
1369
|
+
const perms = UserPermissions.InitEmpty();
|
|
1370
|
+
const jsonVal = perms.toProto().toJson();
|
|
1371
|
+
const restored = UserPermissions.fromJson(jsonVal, BigIntify);
|
|
1372
|
+
expect(restored).toBeTruthy();
|
|
1373
|
+
});
|
|
1374
|
+
it('should round-trip through JSON string', () => {
|
|
1375
|
+
const perms = UserPermissions.InitEmpty();
|
|
1376
|
+
const jsonStr = perms.toProto().toJsonString();
|
|
1377
|
+
const restored = UserPermissions.fromJsonString(jsonStr, BigIntify);
|
|
1378
|
+
expect(restored).toBeTruthy();
|
|
1379
|
+
});
|
|
1380
|
+
it('should toBech32Addresses without throwing on empty permissions', () => {
|
|
1381
|
+
const perms = UserPermissions.InitEmpty();
|
|
1382
|
+
expect(() => perms.toBech32Addresses('bb')).not.toThrow();
|
|
1383
|
+
});
|
|
1384
|
+
});
|
|
1385
|
+
describe('UserPermissionsWithDetails - constructor with data', () => {
|
|
1386
|
+
it('should map all arrays when constructed with non-empty data (covers constructor map bodies)', () => {
|
|
1387
|
+
const makeOutgoingWithDetails = () => new UserOutgoingApprovalPermissionWithDetails({
|
|
1388
|
+
toListId: 'All',
|
|
1389
|
+
initiatedByListId: 'All',
|
|
1390
|
+
approvalId: 'All',
|
|
1391
|
+
transferTimes: [{ start: 1n, end: 100n }],
|
|
1392
|
+
tokenIds: [{ start: 1n, end: 10n }],
|
|
1393
|
+
ownershipTimes: [{ start: 1n, end: 100n }],
|
|
1394
|
+
permanentlyPermittedTimes: [{ start: 1n, end: 50n }],
|
|
1395
|
+
permanentlyForbiddenTimes: [],
|
|
1396
|
+
toList: allAddresses(),
|
|
1397
|
+
initiatedByList: allAddresses()
|
|
1398
|
+
});
|
|
1399
|
+
const makeIncomingWithDetails = () => new UserIncomingApprovalPermissionWithDetails({
|
|
1400
|
+
fromListId: 'All',
|
|
1401
|
+
initiatedByListId: 'All',
|
|
1402
|
+
approvalId: 'All',
|
|
1403
|
+
transferTimes: [{ start: 1n, end: 100n }],
|
|
1404
|
+
tokenIds: [{ start: 1n, end: 10n }],
|
|
1405
|
+
ownershipTimes: [{ start: 1n, end: 100n }],
|
|
1406
|
+
permanentlyPermittedTimes: [],
|
|
1407
|
+
permanentlyForbiddenTimes: [{ start: 1n, end: 50n }],
|
|
1408
|
+
fromList: allAddresses(),
|
|
1409
|
+
initiatedByList: allAddresses()
|
|
1410
|
+
});
|
|
1411
|
+
const perms = new UserPermissionsWithDetails({
|
|
1412
|
+
canUpdateOutgoingApprovals: [makeOutgoingWithDetails()],
|
|
1413
|
+
canUpdateIncomingApprovals: [makeIncomingWithDetails()],
|
|
1414
|
+
canUpdateAutoApproveSelfInitiatedOutgoingTransfers: [
|
|
1415
|
+
new ActionPermission({ permanentlyPermittedTimes: [{ start: 1n, end: 100n }], permanentlyForbiddenTimes: [] })
|
|
1416
|
+
],
|
|
1417
|
+
canUpdateAutoApproveSelfInitiatedIncomingTransfers: [
|
|
1418
|
+
new ActionPermission({ permanentlyPermittedTimes: [], permanentlyForbiddenTimes: [{ start: 1n, end: 10n }] })
|
|
1419
|
+
],
|
|
1420
|
+
canUpdateAutoApproveAllIncomingTransfers: [
|
|
1421
|
+
new ActionPermission({ permanentlyPermittedTimes: [{ start: 10n, end: 20n }], permanentlyForbiddenTimes: [] })
|
|
1422
|
+
]
|
|
1423
|
+
});
|
|
1424
|
+
expect(perms.canUpdateOutgoingApprovals.length).toBe(1);
|
|
1425
|
+
expect(perms.canUpdateOutgoingApprovals[0].toList).toBeDefined();
|
|
1426
|
+
expect(perms.canUpdateIncomingApprovals.length).toBe(1);
|
|
1427
|
+
expect(perms.canUpdateIncomingApprovals[0].fromList).toBeDefined();
|
|
1428
|
+
expect(perms.canUpdateAutoApproveSelfInitiatedOutgoingTransfers.length).toBe(1);
|
|
1429
|
+
expect(perms.canUpdateAutoApproveSelfInitiatedIncomingTransfers.length).toBe(1);
|
|
1430
|
+
expect(perms.canUpdateAutoApproveAllIncomingTransfers.length).toBe(1);
|
|
1431
|
+
});
|
|
1432
|
+
it('should convert UserPermissionsWithDetails using convert()', () => {
|
|
1433
|
+
const perms = new UserPermissionsWithDetails({
|
|
1434
|
+
canUpdateOutgoingApprovals: [
|
|
1435
|
+
new UserOutgoingApprovalPermissionWithDetails({
|
|
1436
|
+
toListId: 'All',
|
|
1437
|
+
initiatedByListId: 'All',
|
|
1438
|
+
approvalId: 'All',
|
|
1439
|
+
transferTimes: [{ start: 1n, end: 100n }],
|
|
1440
|
+
tokenIds: [{ start: 1n, end: 10n }],
|
|
1441
|
+
ownershipTimes: [{ start: 1n, end: 100n }],
|
|
1442
|
+
permanentlyPermittedTimes: [{ start: 1n, end: 50n }],
|
|
1443
|
+
permanentlyForbiddenTimes: [],
|
|
1444
|
+
toList: allAddresses(),
|
|
1445
|
+
initiatedByList: allAddresses()
|
|
1446
|
+
})
|
|
1447
|
+
],
|
|
1448
|
+
canUpdateIncomingApprovals: [],
|
|
1449
|
+
canUpdateAutoApproveSelfInitiatedOutgoingTransfers: [],
|
|
1450
|
+
canUpdateAutoApproveSelfInitiatedIncomingTransfers: [],
|
|
1451
|
+
canUpdateAutoApproveAllIncomingTransfers: []
|
|
1452
|
+
});
|
|
1453
|
+
const converted = perms.convert(Stringify);
|
|
1454
|
+
expect(converted.canUpdateOutgoingApprovals[0].tokenIds[0].start).toBe('1');
|
|
1455
|
+
});
|
|
1456
|
+
});
|
|
1457
|
+
describe('CollectionApprovalPermissionWithDetails - clone and convert', () => {
|
|
1458
|
+
it('should clone successfully', () => {
|
|
1459
|
+
const perm = new CollectionApprovalPermissionWithDetails({
|
|
1460
|
+
fromListId: 'All',
|
|
1461
|
+
toListId: 'All',
|
|
1462
|
+
initiatedByListId: 'All',
|
|
1463
|
+
approvalId: 'All',
|
|
1464
|
+
transferTimes: [{ start: 1n, end: 100n }],
|
|
1465
|
+
tokenIds: [{ start: 1n, end: 10n }],
|
|
1466
|
+
ownershipTimes: [{ start: 1n, end: 100n }],
|
|
1467
|
+
permanentlyPermittedTimes: [{ start: 1n, end: 50n }],
|
|
1468
|
+
permanentlyForbiddenTimes: [],
|
|
1469
|
+
fromList: allAddresses(),
|
|
1470
|
+
toList: allAddresses(),
|
|
1471
|
+
initiatedByList: allAddresses()
|
|
1472
|
+
});
|
|
1473
|
+
const cloned = perm.clone();
|
|
1474
|
+
expect(cloned).toBeTruthy();
|
|
1475
|
+
expect(cloned.fromListId).toBe('All');
|
|
1476
|
+
});
|
|
1477
|
+
it('should convert to string type', () => {
|
|
1478
|
+
const perm = new CollectionApprovalPermissionWithDetails({
|
|
1479
|
+
fromListId: 'All',
|
|
1480
|
+
toListId: 'All',
|
|
1481
|
+
initiatedByListId: 'All',
|
|
1482
|
+
approvalId: 'All',
|
|
1483
|
+
transferTimes: [{ start: 1n, end: 100n }],
|
|
1484
|
+
tokenIds: [{ start: 1n, end: 10n }],
|
|
1485
|
+
ownershipTimes: [{ start: 1n, end: 100n }],
|
|
1486
|
+
permanentlyPermittedTimes: [{ start: 5n, end: 50n }],
|
|
1487
|
+
permanentlyForbiddenTimes: [],
|
|
1488
|
+
fromList: allAddresses(),
|
|
1489
|
+
toList: allAddresses(),
|
|
1490
|
+
initiatedByList: allAddresses()
|
|
1491
|
+
});
|
|
1492
|
+
const converted = perm.convert(Stringify);
|
|
1493
|
+
expect(converted.permanentlyPermittedTimes[0].start).toBe('5');
|
|
1494
|
+
expect(converted.tokenIds[0].start).toBe('1');
|
|
1495
|
+
});
|
|
1496
|
+
});
|
|
1497
|
+
describe('UserIncomingApprovalPermissionWithDetails - clone and convert', () => {
|
|
1498
|
+
const makeIncomingWithDetails = () => new UserIncomingApprovalPermissionWithDetails({
|
|
1499
|
+
fromListId: 'All',
|
|
1500
|
+
initiatedByListId: 'All',
|
|
1501
|
+
approvalId: 'All',
|
|
1502
|
+
transferTimes: [{ start: 1n, end: 100n }],
|
|
1503
|
+
tokenIds: [{ start: 1n, end: 10n }],
|
|
1504
|
+
ownershipTimes: [{ start: 1n, end: 100n }],
|
|
1505
|
+
permanentlyPermittedTimes: [{ start: 1n, end: 50n }],
|
|
1506
|
+
permanentlyForbiddenTimes: [],
|
|
1507
|
+
fromList: allAddresses(),
|
|
1508
|
+
initiatedByList: allAddresses()
|
|
1509
|
+
});
|
|
1510
|
+
it('should clone successfully', () => {
|
|
1511
|
+
const perm = makeIncomingWithDetails();
|
|
1512
|
+
const cloned = perm.clone();
|
|
1513
|
+
expect(cloned).toBeTruthy();
|
|
1514
|
+
expect(cloned.fromListId).toBe('All');
|
|
1515
|
+
expect(cloned.fromList).toBeDefined();
|
|
1516
|
+
});
|
|
1517
|
+
it('should convert to string type', () => {
|
|
1518
|
+
const perm = makeIncomingWithDetails();
|
|
1519
|
+
const converted = perm.convert(Stringify);
|
|
1520
|
+
expect(converted.tokenIds[0].start).toBe('1');
|
|
1521
|
+
expect(converted.permanentlyPermittedTimes[0].start).toBe('1');
|
|
1522
|
+
});
|
|
1523
|
+
it('should castToCollectionApprovalPermission with toList set', () => {
|
|
1524
|
+
const perm = makeIncomingWithDetails();
|
|
1525
|
+
const addr = genTestAddress();
|
|
1526
|
+
const casted = perm.castToCollectionApprovalPermission(addr);
|
|
1527
|
+
expect(casted.toListId).toBe(addr);
|
|
1528
|
+
expect(casted.toList).toBeDefined();
|
|
1529
|
+
});
|
|
1530
|
+
});
|
|
1531
|
+
describe('UserOutgoingApprovalPermissionWithDetails - clone and convert', () => {
|
|
1532
|
+
const makeOutgoingWithDetails = () => new UserOutgoingApprovalPermissionWithDetails({
|
|
1533
|
+
toListId: 'All',
|
|
1534
|
+
initiatedByListId: 'All',
|
|
1535
|
+
approvalId: 'All',
|
|
1536
|
+
transferTimes: [{ start: 1n, end: 100n }],
|
|
1537
|
+
tokenIds: [{ start: 1n, end: 10n }],
|
|
1538
|
+
ownershipTimes: [{ start: 1n, end: 100n }],
|
|
1539
|
+
permanentlyPermittedTimes: [{ start: 1n, end: 50n }],
|
|
1540
|
+
permanentlyForbiddenTimes: [],
|
|
1541
|
+
toList: allAddresses(),
|
|
1542
|
+
initiatedByList: allAddresses()
|
|
1543
|
+
});
|
|
1544
|
+
it('should clone successfully', () => {
|
|
1545
|
+
const perm = makeOutgoingWithDetails();
|
|
1546
|
+
const cloned = perm.clone();
|
|
1547
|
+
expect(cloned).toBeTruthy();
|
|
1548
|
+
expect(cloned.toListId).toBe('All');
|
|
1549
|
+
expect(cloned.toList).toBeDefined();
|
|
1550
|
+
});
|
|
1551
|
+
it('should convert to string type', () => {
|
|
1552
|
+
const perm = makeOutgoingWithDetails();
|
|
1553
|
+
const converted = perm.convert(Stringify);
|
|
1554
|
+
expect(converted.tokenIds[0].start).toBe('1');
|
|
1555
|
+
expect(converted.permanentlyPermittedTimes[0].start).toBe('1');
|
|
1556
|
+
});
|
|
1557
|
+
it('should castToCollectionApprovalPermission with fromList set', () => {
|
|
1558
|
+
const perm = makeOutgoingWithDetails();
|
|
1559
|
+
const addr = genTestAddress();
|
|
1560
|
+
const casted = perm.castToCollectionApprovalPermission(addr);
|
|
1561
|
+
expect(casted.fromListId).toBe(addr);
|
|
1562
|
+
expect(casted.fromList).toBeDefined();
|
|
1563
|
+
});
|
|
1564
|
+
});
|
|
1565
|
+
describe('CollectionApprovalPermission.check - extended error messages', () => {
|
|
1566
|
+
it('should include timeline times in error message when usesLists=true and forbidden', () => {
|
|
1567
|
+
const addr = genTestAddress();
|
|
1568
|
+
const perm = new CollectionApprovalPermissionWithDetails({
|
|
1569
|
+
fromListId: 'All',
|
|
1570
|
+
toListId: addr,
|
|
1571
|
+
initiatedByListId: 'All',
|
|
1572
|
+
approvalId: 'All',
|
|
1573
|
+
transferTimes: [{ start: 1n, end: 18446744073709551615n }],
|
|
1574
|
+
tokenIds: [{ start: 1n, end: 18446744073709551615n }],
|
|
1575
|
+
ownershipTimes: [{ start: 1n, end: 18446744073709551615n }],
|
|
1576
|
+
permanentlyPermittedTimes: [],
|
|
1577
|
+
permanentlyForbiddenTimes: [{ start: 1n, end: 18446744073709551615n }],
|
|
1578
|
+
fromList: allAddresses(),
|
|
1579
|
+
toList: whitelistOf([addr]),
|
|
1580
|
+
initiatedByList: allAddresses()
|
|
1581
|
+
});
|
|
1582
|
+
const err = CollectionApprovalPermission.check([
|
|
1583
|
+
{
|
|
1584
|
+
tokenIds: UintRangeArray.From([{ start: 1n, end: 5n }]),
|
|
1585
|
+
ownershipTimes: fullRange(),
|
|
1586
|
+
transferTimes: fullRange(),
|
|
1587
|
+
toList: whitelistOf([addr]),
|
|
1588
|
+
fromList: allAddresses(),
|
|
1589
|
+
initiatedByList: allAddresses(),
|
|
1590
|
+
approvalIdList: allAddresses()
|
|
1591
|
+
}
|
|
1592
|
+
], [perm], 50n);
|
|
1593
|
+
expect(err).not.toBeNull();
|
|
1594
|
+
expect(err.message).toContain('forbidden');
|
|
1595
|
+
});
|
|
1596
|
+
});
|
|
1597
|
+
describe('validateUniversalPermissionUpdate - multiple missing and combined error', () => {
|
|
1598
|
+
it('should mention count when multiple permissions are missing', () => {
|
|
1599
|
+
const makeSimpleWithDetails = (tokenStart, tokenEnd) => new CollectionApprovalPermissionWithDetails({
|
|
1600
|
+
fromListId: 'All',
|
|
1601
|
+
toListId: 'All',
|
|
1602
|
+
initiatedByListId: 'All',
|
|
1603
|
+
approvalId: 'All',
|
|
1604
|
+
transferTimes: [{ start: 1n, end: 1n }],
|
|
1605
|
+
tokenIds: [{ start: tokenStart, end: tokenEnd }],
|
|
1606
|
+
ownershipTimes: [{ start: 1n, end: 1n }],
|
|
1607
|
+
permanentlyPermittedTimes: [{ start: 1n, end: 100n }],
|
|
1608
|
+
permanentlyForbiddenTimes: [],
|
|
1609
|
+
fromList: allAddresses(),
|
|
1610
|
+
toList: allAddresses(),
|
|
1611
|
+
initiatedByList: allAddresses()
|
|
1612
|
+
});
|
|
1613
|
+
const oldPerms = [makeSimpleWithDetails(1n, 5n), makeSimpleWithDetails(10n, 15n)];
|
|
1614
|
+
const newPerms = [];
|
|
1615
|
+
const err = CollectionApprovalPermission.validateUpdate(oldPerms, newPerms);
|
|
1616
|
+
expect(err).not.toBeNull();
|
|
1617
|
+
expect(err.message).toMatch(/along with|found in old/);
|
|
1618
|
+
});
|
|
1619
|
+
it('should produce combined permitted+forbidden error when both are being removed', () => {
|
|
1620
|
+
const makeApprovalWithBoth = (permitted, forbidden) => new CollectionApprovalPermissionWithDetails({
|
|
1621
|
+
fromListId: 'All',
|
|
1622
|
+
toListId: 'All',
|
|
1623
|
+
initiatedByListId: 'All',
|
|
1624
|
+
approvalId: 'All',
|
|
1625
|
+
transferTimes: [{ start: 1n, end: 1n }],
|
|
1626
|
+
tokenIds: [{ start: 1n, end: 10n }],
|
|
1627
|
+
ownershipTimes: [{ start: 1n, end: 1n }],
|
|
1628
|
+
permanentlyPermittedTimes: permitted.map(([s, e]) => ({ start: s, end: e })),
|
|
1629
|
+
permanentlyForbiddenTimes: forbidden.map(([s, e]) => ({ start: s, end: e })),
|
|
1630
|
+
fromList: allAddresses(),
|
|
1631
|
+
toList: allAddresses(),
|
|
1632
|
+
initiatedByList: allAddresses()
|
|
1633
|
+
});
|
|
1634
|
+
const oldPerms = [makeApprovalWithBoth([[1n, 50n]], [[51n, 100n]])];
|
|
1635
|
+
const newPerms = [makeApprovalWithBoth([], [])];
|
|
1636
|
+
const err = CollectionApprovalPermission.validateUpdate(oldPerms, newPerms);
|
|
1637
|
+
expect(err).not.toBeNull();
|
|
1638
|
+
expect(err.message).toMatch(/allowed|disApproved/i);
|
|
1639
|
+
});
|
|
1640
|
+
});
|
|
1641
|
+
describe('CollectionPermissionsWithDetails - constructor with canUpdateCollectionApprovals', () => {
|
|
1642
|
+
it('should map canUpdateCollectionApprovals to CollectionApprovalPermissionWithDetails (covers lines 1014-1023)', () => {
|
|
1643
|
+
const perms = new CollectionPermissionsWithDetails({
|
|
1644
|
+
canDeleteCollection: [],
|
|
1645
|
+
canArchiveCollection: [],
|
|
1646
|
+
canUpdateStandards: [],
|
|
1647
|
+
canUpdateCustomData: [],
|
|
1648
|
+
canUpdateManager: [],
|
|
1649
|
+
canUpdateCollectionMetadata: [],
|
|
1650
|
+
canUpdateValidTokenIds: [],
|
|
1651
|
+
canUpdateTokenMetadata: [],
|
|
1652
|
+
canUpdateCollectionApprovals: [
|
|
1653
|
+
new CollectionApprovalPermissionWithDetails({
|
|
1654
|
+
fromListId: 'All',
|
|
1655
|
+
toListId: 'All',
|
|
1656
|
+
initiatedByListId: 'All',
|
|
1657
|
+
approvalId: 'All',
|
|
1658
|
+
transferTimes: [{ start: 1n, end: 18446744073709551615n }],
|
|
1659
|
+
tokenIds: [{ start: 1n, end: 18446744073709551615n }],
|
|
1660
|
+
ownershipTimes: [{ start: 1n, end: 18446744073709551615n }],
|
|
1661
|
+
permanentlyPermittedTimes: [{ start: 1n, end: 100n }],
|
|
1662
|
+
permanentlyForbiddenTimes: [],
|
|
1663
|
+
fromList: allAddresses(),
|
|
1664
|
+
toList: allAddresses(),
|
|
1665
|
+
initiatedByList: allAddresses()
|
|
1666
|
+
})
|
|
1667
|
+
],
|
|
1668
|
+
canAddMoreAliasPaths: [],
|
|
1669
|
+
canAddMoreCosmosCoinWrapperPaths: []
|
|
1670
|
+
});
|
|
1671
|
+
expect(perms.canUpdateCollectionApprovals.length).toBe(1);
|
|
1672
|
+
expect(perms.canUpdateCollectionApprovals[0].fromList).toBeDefined();
|
|
1673
|
+
expect(perms.canUpdateCollectionApprovals[0].permanentlyPermittedTimes[0].start).toBe(1n);
|
|
1674
|
+
});
|
|
1675
|
+
it('should clone CollectionPermissionsWithDetails', () => {
|
|
1676
|
+
const perms = new CollectionPermissionsWithDetails({
|
|
1677
|
+
canDeleteCollection: [],
|
|
1678
|
+
canArchiveCollection: [],
|
|
1679
|
+
canUpdateStandards: [],
|
|
1680
|
+
canUpdateCustomData: [],
|
|
1681
|
+
canUpdateManager: [],
|
|
1682
|
+
canUpdateCollectionMetadata: [],
|
|
1683
|
+
canUpdateValidTokenIds: [],
|
|
1684
|
+
canUpdateTokenMetadata: [],
|
|
1685
|
+
canUpdateCollectionApprovals: [],
|
|
1686
|
+
canAddMoreAliasPaths: [],
|
|
1687
|
+
canAddMoreCosmosCoinWrapperPaths: []
|
|
1688
|
+
});
|
|
1689
|
+
const cloned = perms.clone();
|
|
1690
|
+
expect(cloned).toBeTruthy();
|
|
1691
|
+
});
|
|
1692
|
+
it('should convert CollectionPermissionsWithDetails (covers line 1019)', () => {
|
|
1693
|
+
const perms = new CollectionPermissionsWithDetails({
|
|
1694
|
+
canDeleteCollection: [],
|
|
1695
|
+
canArchiveCollection: [],
|
|
1696
|
+
canUpdateStandards: [],
|
|
1697
|
+
canUpdateCustomData: [],
|
|
1698
|
+
canUpdateManager: [
|
|
1699
|
+
new ActionPermission({
|
|
1700
|
+
permanentlyPermittedTimes: [{ start: 1n, end: 100n }],
|
|
1701
|
+
permanentlyForbiddenTimes: []
|
|
1702
|
+
})
|
|
1703
|
+
],
|
|
1704
|
+
canUpdateCollectionMetadata: [],
|
|
1705
|
+
canUpdateValidTokenIds: [],
|
|
1706
|
+
canUpdateTokenMetadata: [],
|
|
1707
|
+
canUpdateCollectionApprovals: [
|
|
1708
|
+
new CollectionApprovalPermissionWithDetails({
|
|
1709
|
+
fromListId: 'All',
|
|
1710
|
+
toListId: 'All',
|
|
1711
|
+
initiatedByListId: 'All',
|
|
1712
|
+
approvalId: 'All',
|
|
1713
|
+
transferTimes: [{ start: 1n, end: 18446744073709551615n }],
|
|
1714
|
+
tokenIds: [{ start: 1n, end: 18446744073709551615n }],
|
|
1715
|
+
ownershipTimes: [{ start: 1n, end: 18446744073709551615n }],
|
|
1716
|
+
permanentlyPermittedTimes: [{ start: 5n, end: 50n }],
|
|
1717
|
+
permanentlyForbiddenTimes: [],
|
|
1718
|
+
fromList: allAddresses(),
|
|
1719
|
+
toList: allAddresses(),
|
|
1720
|
+
initiatedByList: allAddresses()
|
|
1721
|
+
})
|
|
1722
|
+
],
|
|
1723
|
+
canAddMoreAliasPaths: [],
|
|
1724
|
+
canAddMoreCosmosCoinWrapperPaths: []
|
|
1725
|
+
});
|
|
1726
|
+
const converted = perms.convert(Stringify);
|
|
1727
|
+
expect(converted.canUpdateManager[0].permanentlyPermittedTimes[0].start).toBe('1');
|
|
1728
|
+
expect(converted.canUpdateCollectionApprovals[0].permanentlyPermittedTimes[0].start).toBe('5');
|
|
1729
|
+
});
|
|
1730
|
+
});
|
|
1731
|
+
describe('getPermissionString branches - whitelist and address listing', () => {
|
|
1732
|
+
it('should produce error message with whitelist address info when whitelist=true', () => {
|
|
1733
|
+
const addr1 = genTestAddress();
|
|
1734
|
+
const addr2 = genTestAddress();
|
|
1735
|
+
const makeWithWhitelist = () => new CollectionApprovalPermissionWithDetails({
|
|
1736
|
+
fromListId: 'All',
|
|
1737
|
+
toListId: 'whitelist-test',
|
|
1738
|
+
initiatedByListId: 'All',
|
|
1739
|
+
approvalId: 'All',
|
|
1740
|
+
transferTimes: [{ start: 1n, end: 1n }],
|
|
1741
|
+
tokenIds: [{ start: 1n, end: 5n }],
|
|
1742
|
+
ownershipTimes: [{ start: 1n, end: 1n }],
|
|
1743
|
+
permanentlyPermittedTimes: [{ start: 1n, end: 100n }],
|
|
1744
|
+
permanentlyForbiddenTimes: [],
|
|
1745
|
+
fromList: whitelistOf([addr1, addr2]),
|
|
1746
|
+
toList: whitelistOf([addr1, addr2]),
|
|
1747
|
+
initiatedByList: whitelistOf([addr1, addr2])
|
|
1748
|
+
});
|
|
1749
|
+
const oldPerms = [makeWithWhitelist()];
|
|
1750
|
+
const newPerms = [];
|
|
1751
|
+
const err = CollectionApprovalPermission.validateUpdate(oldPerms, newPerms);
|
|
1752
|
+
expect(err).not.toBeNull();
|
|
1753
|
+
expect(err.message).toContain('found in old permissions');
|
|
1754
|
+
});
|
|
1755
|
+
});
|
|
1756
|
+
describe('UserOutgoingApprovalPermission', () => {
|
|
1757
|
+
const makeOutgoingPerm = (opts) => {
|
|
1758
|
+
return new UserOutgoingApprovalPermissionWithDetails({
|
|
1759
|
+
toListId: 'All',
|
|
1760
|
+
initiatedByListId: 'All',
|
|
1761
|
+
approvalId: 'All',
|
|
1762
|
+
tokenIds: [{ start: 1n, end: 18446744073709551615n }],
|
|
1763
|
+
transferTimes: [{ start: 1n, end: 18446744073709551615n }],
|
|
1764
|
+
ownershipTimes: [{ start: 1n, end: 18446744073709551615n }],
|
|
1765
|
+
permanentlyPermittedTimes: (opts.permitted || []).map(([s, e]) => ({ start: s, end: e })),
|
|
1766
|
+
permanentlyForbiddenTimes: (opts.forbidden || []).map(([s, e]) => ({ start: s, end: e })),
|
|
1767
|
+
toList: allAddresses(),
|
|
1768
|
+
initiatedByList: allAddresses()
|
|
1769
|
+
});
|
|
1770
|
+
};
|
|
1771
|
+
describe('construction', () => {
|
|
1772
|
+
it('should create an instance', () => {
|
|
1773
|
+
const perm = makeOutgoingPerm({ permitted: [[1n, 100n]] });
|
|
1774
|
+
expect(perm).toBeTruthy();
|
|
1775
|
+
expect(perm.toListId).toBe('All');
|
|
1776
|
+
expect(perm.initiatedByListId).toBe('All');
|
|
1777
|
+
});
|
|
1778
|
+
});
|
|
1779
|
+
describe('castToCollectionApprovalPermission', () => {
|
|
1780
|
+
it('should cast with a valid address for from field', () => {
|
|
1781
|
+
const perm = makeOutgoingPerm({});
|
|
1782
|
+
const addr = genTestAddress();
|
|
1783
|
+
const castedPerm = perm.castToCollectionApprovalPermission(addr);
|
|
1784
|
+
expect(castedPerm).toBeTruthy();
|
|
1785
|
+
expect(castedPerm.fromListId).toBe(addr);
|
|
1786
|
+
});
|
|
1787
|
+
it('should throw when using invalid dummy address "0x"', () => {
|
|
1788
|
+
const perm = makeOutgoingPerm({});
|
|
1789
|
+
expect(() => perm.castToCollectionApprovalPermission('0x')).toThrow('Invalid address list ID');
|
|
1790
|
+
});
|
|
1791
|
+
});
|
|
1792
|
+
describe('validateUpdate', () => {
|
|
1793
|
+
it('should allow identical outgoing approval permissions', () => {
|
|
1794
|
+
const perms = [makeOutgoingPerm({ permitted: [[1n, 100n]] })];
|
|
1795
|
+
const result = UserOutgoingApprovalPermission.validateUpdate(perms, perms);
|
|
1796
|
+
expect(result).toBeNull();
|
|
1797
|
+
});
|
|
1798
|
+
it('should reject shrinking permitted times', () => {
|
|
1799
|
+
const oldPerms = [makeOutgoingPerm({ permitted: [[1n, 100n]] })];
|
|
1800
|
+
const newPerms = [makeOutgoingPerm({ permitted: [[1n, 50n]] })];
|
|
1801
|
+
const result = UserOutgoingApprovalPermission.validateUpdate(oldPerms, newPerms);
|
|
1802
|
+
expect(result).not.toBeNull();
|
|
1803
|
+
});
|
|
1804
|
+
});
|
|
1805
|
+
});
|
|
1806
|
+
describe('UserIncomingApprovalPermission', () => {
|
|
1807
|
+
const makeIncomingPerm = (opts) => {
|
|
1808
|
+
return new UserIncomingApprovalPermissionWithDetails({
|
|
1809
|
+
fromListId: 'All',
|
|
1810
|
+
initiatedByListId: 'All',
|
|
1811
|
+
approvalId: 'All',
|
|
1812
|
+
tokenIds: [{ start: 1n, end: 18446744073709551615n }],
|
|
1813
|
+
transferTimes: [{ start: 1n, end: 18446744073709551615n }],
|
|
1814
|
+
ownershipTimes: [{ start: 1n, end: 18446744073709551615n }],
|
|
1815
|
+
permanentlyPermittedTimes: (opts.permitted || []).map(([s, e]) => ({ start: s, end: e })),
|
|
1816
|
+
permanentlyForbiddenTimes: (opts.forbidden || []).map(([s, e]) => ({ start: s, end: e })),
|
|
1817
|
+
fromList: allAddresses(),
|
|
1818
|
+
initiatedByList: allAddresses()
|
|
1819
|
+
});
|
|
1820
|
+
};
|
|
1821
|
+
describe('construction', () => {
|
|
1822
|
+
it('should create an instance', () => {
|
|
1823
|
+
const perm = makeIncomingPerm({ permitted: [[1n, 100n]] });
|
|
1824
|
+
expect(perm).toBeTruthy();
|
|
1825
|
+
expect(perm.fromListId).toBe('All');
|
|
1826
|
+
});
|
|
1827
|
+
});
|
|
1828
|
+
describe('castToCollectionApprovalPermission', () => {
|
|
1829
|
+
it('should cast with a valid address for to field', () => {
|
|
1830
|
+
const perm = makeIncomingPerm({});
|
|
1831
|
+
const addr = genTestAddress();
|
|
1832
|
+
const castedPerm = perm.castToCollectionApprovalPermission(addr);
|
|
1833
|
+
expect(castedPerm).toBeTruthy();
|
|
1834
|
+
expect(castedPerm.toListId).toBe(addr);
|
|
1835
|
+
});
|
|
1836
|
+
it('should throw when using invalid dummy address "0x"', () => {
|
|
1837
|
+
const perm = makeIncomingPerm({});
|
|
1838
|
+
expect(() => perm.castToCollectionApprovalPermission('0x')).toThrow('Invalid address list ID');
|
|
1839
|
+
});
|
|
1840
|
+
});
|
|
1841
|
+
describe('validateUpdate', () => {
|
|
1842
|
+
it('should allow identical incoming approval permissions', () => {
|
|
1843
|
+
const perms = [makeIncomingPerm({ permitted: [[1n, 100n]] })];
|
|
1844
|
+
const result = UserIncomingApprovalPermission.validateUpdate(perms, perms);
|
|
1845
|
+
expect(result).toBeNull();
|
|
1846
|
+
});
|
|
1847
|
+
it('should reject changing permitted to forbidden', () => {
|
|
1848
|
+
const oldPerms = [makeIncomingPerm({ permitted: [[1n, 100n]] })];
|
|
1849
|
+
const newPerms = [makeIncomingPerm({ forbidden: [[1n, 100n]] })];
|
|
1850
|
+
const result = UserIncomingApprovalPermission.validateUpdate(oldPerms, newPerms);
|
|
1851
|
+
expect(result).not.toBeNull();
|
|
1852
|
+
});
|
|
1853
|
+
it('should allow extending forbidden times', () => {
|
|
1854
|
+
const oldPerms = [makeIncomingPerm({ forbidden: [[1n, 50n]] })];
|
|
1855
|
+
const newPerms = [makeIncomingPerm({ forbidden: [[1n, 100n]] })];
|
|
1856
|
+
const result = UserIncomingApprovalPermission.validateUpdate(oldPerms, newPerms);
|
|
1857
|
+
expect(result).toBeNull();
|
|
1858
|
+
});
|
|
1859
|
+
});
|
|
1860
|
+
});
|
|
1861
|
+
describe('Permissions edge cases', () => {
|
|
1862
|
+
describe('Multiple permissions - first match only semantics', () => {
|
|
1863
|
+
it('should use first match when multiple action permissions overlap', () => {
|
|
1864
|
+
const perms = [
|
|
1865
|
+
new ActionPermission({
|
|
1866
|
+
permanentlyPermittedTimes: [],
|
|
1867
|
+
permanentlyForbiddenTimes: [{ start: 1n, end: 50n }]
|
|
1868
|
+
}),
|
|
1869
|
+
new ActionPermission({
|
|
1870
|
+
permanentlyPermittedTimes: [{ start: 1n, end: 100n }],
|
|
1871
|
+
permanentlyForbiddenTimes: []
|
|
1872
|
+
})
|
|
1873
|
+
];
|
|
1874
|
+
const err1 = ActionPermission.check(perms, 25n);
|
|
1875
|
+
expect(err1).not.toBeNull();
|
|
1876
|
+
const err2 = ActionPermission.check(perms, 75n);
|
|
1877
|
+
expect(err2).toBeNull();
|
|
1878
|
+
});
|
|
1879
|
+
});
|
|
1880
|
+
describe('convert method', () => {
|
|
1881
|
+
it('should convert ActionPermission number types', () => {
|
|
1882
|
+
const perm = new ActionPermission({
|
|
1883
|
+
permanentlyPermittedTimes: [{ start: 1n, end: 100n }],
|
|
1884
|
+
permanentlyForbiddenTimes: []
|
|
1885
|
+
});
|
|
1886
|
+
const converted = perm.convert((val) => val.toString());
|
|
1887
|
+
expect(converted.permanentlyPermittedTimes[0].start).toBe('1');
|
|
1888
|
+
expect(converted.permanentlyPermittedTimes[0].end).toBe('100');
|
|
1889
|
+
});
|
|
1890
|
+
it('should convert TokenIdsActionPermission number types', () => {
|
|
1891
|
+
const perm = new TokenIdsActionPermission({
|
|
1892
|
+
tokenIds: [{ start: 1n, end: 10n }],
|
|
1893
|
+
permanentlyPermittedTimes: [{ start: 1n, end: 100n }],
|
|
1894
|
+
permanentlyForbiddenTimes: []
|
|
1895
|
+
});
|
|
1896
|
+
const converted = perm.convert((val) => val.toString());
|
|
1897
|
+
expect(converted.tokenIds[0].start).toBe('1');
|
|
1898
|
+
expect(converted.tokenIds[0].end).toBe('10');
|
|
1899
|
+
expect(converted.permanentlyPermittedTimes[0].start).toBe('1');
|
|
1900
|
+
});
|
|
1901
|
+
it('should convert CollectionPermissions number types', () => {
|
|
1902
|
+
const perms = new CollectionPermissions({
|
|
1903
|
+
canDeleteCollection: [
|
|
1904
|
+
new ActionPermission({
|
|
1905
|
+
permanentlyPermittedTimes: [{ start: 1n, end: 100n }],
|
|
1906
|
+
permanentlyForbiddenTimes: []
|
|
1907
|
+
})
|
|
1908
|
+
],
|
|
1909
|
+
canArchiveCollection: [],
|
|
1910
|
+
canUpdateStandards: [],
|
|
1911
|
+
canUpdateCustomData: [],
|
|
1912
|
+
canUpdateManager: [],
|
|
1913
|
+
canUpdateCollectionMetadata: [],
|
|
1914
|
+
canUpdateValidTokenIds: [],
|
|
1915
|
+
canUpdateTokenMetadata: [],
|
|
1916
|
+
canUpdateCollectionApprovals: [],
|
|
1917
|
+
canAddMoreAliasPaths: [],
|
|
1918
|
+
canAddMoreCosmosCoinWrapperPaths: []
|
|
1919
|
+
});
|
|
1920
|
+
const converted = perms.convert((val) => val.toString());
|
|
1921
|
+
expect(converted.canDeleteCollection[0].permanentlyPermittedTimes[0].start).toBe('1');
|
|
1922
|
+
});
|
|
1923
|
+
});
|
|
1924
|
+
describe('toBech32Addresses', () => {
|
|
1925
|
+
it('should convert UserOutgoingApprovalPermission list IDs to bech32', () => {
|
|
1926
|
+
const addr = genTestAddress();
|
|
1927
|
+
const perm = new UserOutgoingApprovalPermission({
|
|
1928
|
+
toListId: addr,
|
|
1929
|
+
initiatedByListId: 'All',
|
|
1930
|
+
approvalId: 'test',
|
|
1931
|
+
tokenIds: [{ start: 1n, end: 10n }],
|
|
1932
|
+
transferTimes: [{ start: 1n, end: 100n }],
|
|
1933
|
+
ownershipTimes: [{ start: 1n, end: 100n }],
|
|
1934
|
+
permanentlyPermittedTimes: [],
|
|
1935
|
+
permanentlyForbiddenTimes: []
|
|
1936
|
+
});
|
|
1937
|
+
const converted = perm.toBech32Addresses('bb');
|
|
1938
|
+
expect(converted).toBeTruthy();
|
|
1939
|
+
expect(typeof converted.toListId).toBe('string');
|
|
1940
|
+
});
|
|
1941
|
+
it('should convert UserIncomingApprovalPermission list IDs to bech32', () => {
|
|
1942
|
+
const addr = genTestAddress();
|
|
1943
|
+
const perm = new UserIncomingApprovalPermission({
|
|
1944
|
+
fromListId: addr,
|
|
1945
|
+
initiatedByListId: 'All',
|
|
1946
|
+
approvalId: 'test',
|
|
1947
|
+
tokenIds: [{ start: 1n, end: 10n }],
|
|
1948
|
+
transferTimes: [{ start: 1n, end: 100n }],
|
|
1949
|
+
ownershipTimes: [{ start: 1n, end: 100n }],
|
|
1950
|
+
permanentlyPermittedTimes: [],
|
|
1951
|
+
permanentlyForbiddenTimes: []
|
|
1952
|
+
});
|
|
1953
|
+
const converted = perm.toBech32Addresses('bb');
|
|
1954
|
+
expect(converted).toBeTruthy();
|
|
1955
|
+
expect(typeof converted.fromListId).toBe('string');
|
|
1956
|
+
});
|
|
1957
|
+
});
|
|
1958
|
+
describe('Frozen permissions (all-time forbidden)', () => {
|
|
1959
|
+
it('should permanently freeze an action by forbidding all times', () => {
|
|
1960
|
+
const perms = [
|
|
1961
|
+
new ActionPermission({
|
|
1962
|
+
permanentlyPermittedTimes: [],
|
|
1963
|
+
permanentlyForbiddenTimes: [{ start: 1n, end: 18446744073709551615n }]
|
|
1964
|
+
})
|
|
1965
|
+
];
|
|
1966
|
+
for (const time of [1n, 100n, 1000000n, 18446744073709551615n]) {
|
|
1967
|
+
const err = ActionPermission.check(perms, time);
|
|
1968
|
+
expect(err).not.toBeNull();
|
|
1969
|
+
}
|
|
1970
|
+
});
|
|
1971
|
+
it('should not be possible to unfreeze a permanently frozen permission', () => {
|
|
1972
|
+
const frozenPerms = [
|
|
1973
|
+
new ActionPermission({
|
|
1974
|
+
permanentlyPermittedTimes: [],
|
|
1975
|
+
permanentlyForbiddenTimes: [{ start: 1n, end: 18446744073709551615n }]
|
|
1976
|
+
})
|
|
1977
|
+
];
|
|
1978
|
+
const unfrozenPerms = [
|
|
1979
|
+
new ActionPermission({
|
|
1980
|
+
permanentlyPermittedTimes: [{ start: 1n, end: 18446744073709551615n }],
|
|
1981
|
+
permanentlyForbiddenTimes: []
|
|
1982
|
+
})
|
|
1983
|
+
];
|
|
1984
|
+
const err = ActionPermission.validateUpdate(frozenPerms, unfrozenPerms);
|
|
1985
|
+
expect(err).not.toBeNull();
|
|
1986
|
+
});
|
|
1987
|
+
it('should not be possible to remove forbidden times from a frozen permission', () => {
|
|
1988
|
+
const frozenPerms = [
|
|
1989
|
+
new ActionPermission({
|
|
1990
|
+
permanentlyPermittedTimes: [],
|
|
1991
|
+
permanentlyForbiddenTimes: [{ start: 1n, end: 18446744073709551615n }]
|
|
1992
|
+
})
|
|
1993
|
+
];
|
|
1994
|
+
const partiallyUnfrozenPerms = [
|
|
1995
|
+
new ActionPermission({
|
|
1996
|
+
permanentlyPermittedTimes: [],
|
|
1997
|
+
permanentlyForbiddenTimes: [{ start: 1n, end: 100n }]
|
|
1998
|
+
})
|
|
1999
|
+
];
|
|
2000
|
+
const err = ActionPermission.validateUpdate(frozenPerms, partiallyUnfrozenPerms);
|
|
2001
|
+
expect(err).not.toBeNull();
|
|
2002
|
+
});
|
|
2003
|
+
});
|
|
2004
|
+
describe('Permanently permitted permissions (all-time permitted)', () => {
|
|
2005
|
+
it('should permanently allow an action by permitting all times', () => {
|
|
2006
|
+
const perms = [
|
|
2007
|
+
new ActionPermission({
|
|
2008
|
+
permanentlyPermittedTimes: [{ start: 1n, end: 18446744073709551615n }],
|
|
2009
|
+
permanentlyForbiddenTimes: []
|
|
2010
|
+
})
|
|
2011
|
+
];
|
|
2012
|
+
for (const time of [1n, 100n, 1000000n]) {
|
|
2013
|
+
const err = ActionPermission.check(perms, time);
|
|
2014
|
+
expect(err).toBeNull();
|
|
2015
|
+
}
|
|
2016
|
+
});
|
|
2017
|
+
it('should not be possible to revoke a permanently permitted permission', () => {
|
|
2018
|
+
const permittedPerms = [
|
|
2019
|
+
new ActionPermission({
|
|
2020
|
+
permanentlyPermittedTimes: [{ start: 1n, end: 18446744073709551615n }],
|
|
2021
|
+
permanentlyForbiddenTimes: []
|
|
2022
|
+
})
|
|
2023
|
+
];
|
|
2024
|
+
const revokedPerms = [
|
|
2025
|
+
new ActionPermission({
|
|
2026
|
+
permanentlyPermittedTimes: [],
|
|
2027
|
+
permanentlyForbiddenTimes: [{ start: 1n, end: 18446744073709551615n }]
|
|
2028
|
+
})
|
|
2029
|
+
];
|
|
2030
|
+
const err = ActionPermission.validateUpdate(permittedPerms, revokedPerms);
|
|
2031
|
+
expect(err).not.toBeNull();
|
|
2032
|
+
});
|
|
2033
|
+
});
|
|
2034
|
+
describe('Mixed permitted and forbidden times', () => {
|
|
2035
|
+
it('should handle non-overlapping permitted and forbidden time ranges', () => {
|
|
2036
|
+
const perms = [
|
|
2037
|
+
new ActionPermission({
|
|
2038
|
+
permanentlyPermittedTimes: [{ start: 1n, end: 100n }],
|
|
2039
|
+
permanentlyForbiddenTimes: [{ start: 101n, end: 200n }]
|
|
2040
|
+
})
|
|
2041
|
+
];
|
|
2042
|
+
const err1 = ActionPermission.check(perms, 50n);
|
|
2043
|
+
expect(err1).toBeNull();
|
|
2044
|
+
const err2 = ActionPermission.check(perms, 150n);
|
|
2045
|
+
expect(err2).not.toBeNull();
|
|
2046
|
+
});
|
|
2047
|
+
});
|
|
2048
|
+
});
|
|
2049
|
+
//# sourceMappingURL=permissions.spec.js.map
|