@snapshot-labs/snapshot.js 0.12.65 → 0.13.1
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/snapshot.cjs.js +1321 -1281
- package/dist/snapshot.esm.js +1321 -1281
- package/dist/snapshot.min.js +23 -23
- package/dist/src/index.d.ts +17 -3
- package/dist/src/schemas/index.d.ts +17 -3
- package/dist/src/utils.d.ts +1 -1
- package/package.json +1 -1
- package/src/schemas/space.json +19 -7
- package/src/sign/hashedTypes.json +11 -1
- package/src/sign/index.ts +5 -3
- package/src/sign/types.ts +10 -10
- package/src/utils.spec.js +258 -26
- package/src/utils.ts +11 -4
package/dist/src/index.d.ts
CHANGED
|
@@ -155,7 +155,11 @@ declare const _default: {
|
|
|
155
155
|
maxItems: number;
|
|
156
156
|
items: {
|
|
157
157
|
type: string;
|
|
158
|
-
|
|
158
|
+
anyOf: {
|
|
159
|
+
type: string;
|
|
160
|
+
format: string;
|
|
161
|
+
}[];
|
|
162
|
+
errorMessage: string;
|
|
159
163
|
};
|
|
160
164
|
title: string;
|
|
161
165
|
uniqueItems: boolean;
|
|
@@ -165,7 +169,11 @@ declare const _default: {
|
|
|
165
169
|
maxItems: number;
|
|
166
170
|
items: {
|
|
167
171
|
type: string;
|
|
168
|
-
|
|
172
|
+
anyOf: {
|
|
173
|
+
type: string;
|
|
174
|
+
format: string;
|
|
175
|
+
}[];
|
|
176
|
+
errorMessage: string;
|
|
169
177
|
};
|
|
170
178
|
title: string;
|
|
171
179
|
uniqueItems: boolean;
|
|
@@ -175,7 +183,11 @@ declare const _default: {
|
|
|
175
183
|
maxItems: number;
|
|
176
184
|
items: {
|
|
177
185
|
type: string;
|
|
178
|
-
|
|
186
|
+
anyOf: {
|
|
187
|
+
type: string;
|
|
188
|
+
format: string;
|
|
189
|
+
}[];
|
|
190
|
+
errorMessage: string;
|
|
179
191
|
};
|
|
180
192
|
title: string;
|
|
181
193
|
uniqueItems: boolean;
|
|
@@ -270,6 +282,7 @@ declare const _default: {
|
|
|
270
282
|
description: string;
|
|
271
283
|
examples: string[];
|
|
272
284
|
anyOf: {
|
|
285
|
+
type: string;
|
|
273
286
|
format: string;
|
|
274
287
|
}[];
|
|
275
288
|
errorMessage: string;
|
|
@@ -378,6 +391,7 @@ declare const _default: {
|
|
|
378
391
|
title: string;
|
|
379
392
|
examples: string[];
|
|
380
393
|
anyOf: {
|
|
394
|
+
type: string;
|
|
381
395
|
format: string;
|
|
382
396
|
}[];
|
|
383
397
|
errorMessage: string;
|
|
@@ -151,7 +151,11 @@ declare const _default: {
|
|
|
151
151
|
maxItems: number;
|
|
152
152
|
items: {
|
|
153
153
|
type: string;
|
|
154
|
-
|
|
154
|
+
anyOf: {
|
|
155
|
+
type: string;
|
|
156
|
+
format: string;
|
|
157
|
+
}[];
|
|
158
|
+
errorMessage: string;
|
|
155
159
|
};
|
|
156
160
|
title: string;
|
|
157
161
|
uniqueItems: boolean;
|
|
@@ -161,7 +165,11 @@ declare const _default: {
|
|
|
161
165
|
maxItems: number;
|
|
162
166
|
items: {
|
|
163
167
|
type: string;
|
|
164
|
-
|
|
168
|
+
anyOf: {
|
|
169
|
+
type: string;
|
|
170
|
+
format: string;
|
|
171
|
+
}[];
|
|
172
|
+
errorMessage: string;
|
|
165
173
|
};
|
|
166
174
|
title: string;
|
|
167
175
|
uniqueItems: boolean;
|
|
@@ -171,7 +179,11 @@ declare const _default: {
|
|
|
171
179
|
maxItems: number;
|
|
172
180
|
items: {
|
|
173
181
|
type: string;
|
|
174
|
-
|
|
182
|
+
anyOf: {
|
|
183
|
+
type: string;
|
|
184
|
+
format: string;
|
|
185
|
+
}[];
|
|
186
|
+
errorMessage: string;
|
|
175
187
|
};
|
|
176
188
|
title: string;
|
|
177
189
|
uniqueItems: boolean;
|
|
@@ -266,6 +278,7 @@ declare const _default: {
|
|
|
266
278
|
description: string;
|
|
267
279
|
examples: string[];
|
|
268
280
|
anyOf: {
|
|
281
|
+
type: string;
|
|
269
282
|
format: string;
|
|
270
283
|
}[];
|
|
271
284
|
errorMessage: string;
|
|
@@ -374,6 +387,7 @@ declare const _default: {
|
|
|
374
387
|
title: string;
|
|
375
388
|
examples: string[];
|
|
376
389
|
anyOf: {
|
|
390
|
+
type: string;
|
|
377
391
|
format: string;
|
|
378
392
|
}[];
|
|
379
393
|
errorMessage: string;
|
package/dist/src/utils.d.ts
CHANGED
|
@@ -38,7 +38,7 @@ export declare function sleep(time: any): Promise<unknown>;
|
|
|
38
38
|
export declare function getNumberWithOrdinal(n: any): string;
|
|
39
39
|
export declare function isStarknetAddress(address: string): boolean;
|
|
40
40
|
export declare function isEvmAddress(address: string): boolean;
|
|
41
|
-
export declare function getFormattedAddress(address: string, format
|
|
41
|
+
export declare function getFormattedAddress(address: string, format?: 'evm' | 'starknet'): string;
|
|
42
42
|
export { getDelegatesBySpace, SNAPSHOT_SUBGRAPH_URL };
|
|
43
43
|
declare const _default: {
|
|
44
44
|
call: typeof call;
|
package/package.json
CHANGED
package/src/schemas/space.json
CHANGED
|
@@ -154,7 +154,11 @@
|
|
|
154
154
|
"maxItems": 100,
|
|
155
155
|
"items": {
|
|
156
156
|
"type": "string",
|
|
157
|
-
"
|
|
157
|
+
"anyOf": [
|
|
158
|
+
{ "type": "string", "format": "evmAddress" },
|
|
159
|
+
{ "type": "string", "format": "starknetAddress" }
|
|
160
|
+
],
|
|
161
|
+
"errorMessage": "Must be a valid address"
|
|
158
162
|
},
|
|
159
163
|
"title": "members",
|
|
160
164
|
"uniqueItems": true
|
|
@@ -164,7 +168,11 @@
|
|
|
164
168
|
"maxItems": 100,
|
|
165
169
|
"items": {
|
|
166
170
|
"type": "string",
|
|
167
|
-
"
|
|
171
|
+
"anyOf": [
|
|
172
|
+
{ "type": "string", "format": "evmAddress" },
|
|
173
|
+
{ "type": "string", "format": "starknetAddress" }
|
|
174
|
+
],
|
|
175
|
+
"errorMessage": "Must be a valid address"
|
|
168
176
|
},
|
|
169
177
|
"title": "admins",
|
|
170
178
|
"uniqueItems": true
|
|
@@ -174,7 +182,11 @@
|
|
|
174
182
|
"maxItems": 100,
|
|
175
183
|
"items": {
|
|
176
184
|
"type": "string",
|
|
177
|
-
"
|
|
185
|
+
"anyOf": [
|
|
186
|
+
{ "type": "string", "format": "evmAddress" },
|
|
187
|
+
{ "type": "string", "format": "starknetAddress" }
|
|
188
|
+
],
|
|
189
|
+
"errorMessage": "Must be a valid address"
|
|
178
190
|
},
|
|
179
191
|
"title": "moderators",
|
|
180
192
|
"uniqueItems": true
|
|
@@ -270,8 +282,8 @@
|
|
|
270
282
|
"description": "The address of your delegation contract",
|
|
271
283
|
"examples": ["0x3901D0fDe202aF1427216b79f5243f8A022d68cf"],
|
|
272
284
|
"anyOf": [
|
|
273
|
-
{ "format": "evmAddress" },
|
|
274
|
-
{ "format": "starknetAddress" }
|
|
285
|
+
{ "type": "string", "format": "evmAddress" },
|
|
286
|
+
{ "type": "string", "format": "starknetAddress" }
|
|
275
287
|
],
|
|
276
288
|
"errorMessage": "Must be a valid EVM of Starknet address"
|
|
277
289
|
},
|
|
@@ -397,8 +409,8 @@
|
|
|
397
409
|
"title": "Contract address",
|
|
398
410
|
"examples": ["e.g. 0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984"],
|
|
399
411
|
"anyOf": [
|
|
400
|
-
{ "format": "evmAddress" },
|
|
401
|
-
{ "format": "starknetAddress" }
|
|
412
|
+
{ "type": "string", "format": "evmAddress" },
|
|
413
|
+
{ "type": "string", "format": "starknetAddress" }
|
|
402
414
|
],
|
|
403
415
|
"errorMessage": "Must be a valid EVM of Starknet address"
|
|
404
416
|
},
|
|
@@ -64,5 +64,15 @@
|
|
|
64
64
|
"d56782e3b50ac86c25ae292923da8c367e3c9e8e7ea9d8baa435051fe2f430fa": "proposal",
|
|
65
65
|
"df10a7eeabe19301d6018be8b6c5d13231320d7ece64d021043fa172b64f3796": "update-proposal",
|
|
66
66
|
"beda1f464a6112f9ed6335c4614e32a97f0e18ef4ac10b4b1c8239c475f2d8e8": "proposal",
|
|
67
|
-
"ff74674f39ca59b60056ecddaada0cb513c4729e634e99cb778f53ee404ac806": "update-proposal"
|
|
67
|
+
"ff74674f39ca59b60056ecddaada0cb513c4729e634e99cb778f53ee404ac806": "update-proposal",
|
|
68
|
+
"e037b37311c75c995f732b57cd456bdc685e5eac29668698be34388cafb14097": "proposal",
|
|
69
|
+
"9c66485d2c9af4010e89b0352e3f78ce2aa96661c531b1bdbd7042388867e830": "update-proposal",
|
|
70
|
+
"dd19ee4357e5bc813529e1b537b77ccb767135701f0223434f3b53f1ac03dcc6": "delete-proposal",
|
|
71
|
+
"817265460009cfdbde0752fcc7ef629ae7e05a6e8b6cbffab8a7cbf6cd19e87e": "delete-proposal",
|
|
72
|
+
"fb8fa9816cd42974e7f1af671aa548c8c458553364ed809e45042f141de8c0d5": "vote",
|
|
73
|
+
"5f95ed849bafb034c37e340dc06ad6fa6985d674714cb602a6bf11119ffba2a1": "vote-array",
|
|
74
|
+
"afc5911fd9722b3dc5e8b16a552997510644a52d2b229c3868fb1910b112416e": "vote-string",
|
|
75
|
+
"e4b768874f191321f9a6460e15f87e98800c78c1e3104f9d4e443f2ed9b1c45e": "vote",
|
|
76
|
+
"86c81555a3dda45aa7b151c574dc27f7402c23d9b1432156f1daa6c2e15f9891": "vote-array",
|
|
77
|
+
"c0f418890817b3e6deb58fa3182bf8ed7619242666a9087eab28f27a6876e1da": "vote-string"
|
|
68
78
|
}
|
package/src/sign/index.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import fetch from 'cross-fetch';
|
|
2
2
|
import { Web3Provider } from '@ethersproject/providers';
|
|
3
3
|
import { Wallet } from '@ethersproject/wallet';
|
|
4
|
-
import { getAddress } from '@ethersproject/address';
|
|
5
4
|
import {
|
|
6
5
|
Space,
|
|
7
6
|
Proposal,
|
|
@@ -39,6 +38,7 @@ import {
|
|
|
39
38
|
statementTypes
|
|
40
39
|
} from './types';
|
|
41
40
|
import constants from '../constants.json';
|
|
41
|
+
import { getFormattedAddress } from '../utils';
|
|
42
42
|
|
|
43
43
|
const NAME = 'snapshot';
|
|
44
44
|
const VERSION = '0.1.4';
|
|
@@ -74,8 +74,10 @@ export default class Client {
|
|
|
74
74
|
async sign(web3: Web3Provider | Wallet, address: string, message, types) {
|
|
75
75
|
// @ts-ignore
|
|
76
76
|
const signer = web3?.getSigner ? web3.getSigner() : web3;
|
|
77
|
-
const checksumAddress =
|
|
78
|
-
message.from = message.from
|
|
77
|
+
const checksumAddress = getFormattedAddress(address, 'evm');
|
|
78
|
+
message.from = message.from
|
|
79
|
+
? getFormattedAddress(message.from)
|
|
80
|
+
: checksumAddress;
|
|
79
81
|
if (!message.timestamp)
|
|
80
82
|
message.timestamp = parseInt((Date.now() / 1e3).toFixed());
|
|
81
83
|
|
package/src/sign/types.ts
CHANGED
|
@@ -139,7 +139,7 @@ export const spaceTypes = {
|
|
|
139
139
|
|
|
140
140
|
export const proposalTypes = {
|
|
141
141
|
Proposal: [
|
|
142
|
-
{ name: 'from', type: '
|
|
142
|
+
{ name: 'from', type: 'string' },
|
|
143
143
|
{ name: 'space', type: 'string' },
|
|
144
144
|
{ name: 'timestamp', type: 'uint64' },
|
|
145
145
|
{ name: 'type', type: 'string' },
|
|
@@ -160,7 +160,7 @@ export const proposalTypes = {
|
|
|
160
160
|
export const updateProposalTypes = {
|
|
161
161
|
UpdateProposal: [
|
|
162
162
|
{ name: 'proposal', type: 'string' },
|
|
163
|
-
{ name: 'from', type: '
|
|
163
|
+
{ name: 'from', type: 'string' },
|
|
164
164
|
{ name: 'space', type: 'string' },
|
|
165
165
|
{ name: 'timestamp', type: 'uint64' },
|
|
166
166
|
{ name: 'type', type: 'string' },
|
|
@@ -185,7 +185,7 @@ export const flagProposalTypes = {
|
|
|
185
185
|
|
|
186
186
|
export const cancelProposalTypes = {
|
|
187
187
|
CancelProposal: [
|
|
188
|
-
{ name: 'from', type: '
|
|
188
|
+
{ name: 'from', type: 'string' },
|
|
189
189
|
{ name: 'space', type: 'string' },
|
|
190
190
|
{ name: 'timestamp', type: 'uint64' },
|
|
191
191
|
{ name: 'proposal', type: 'string' }
|
|
@@ -194,7 +194,7 @@ export const cancelProposalTypes = {
|
|
|
194
194
|
|
|
195
195
|
export const cancelProposal2Types = {
|
|
196
196
|
CancelProposal: [
|
|
197
|
-
{ name: 'from', type: '
|
|
197
|
+
{ name: 'from', type: 'string' },
|
|
198
198
|
{ name: 'space', type: 'string' },
|
|
199
199
|
{ name: 'timestamp', type: 'uint64' },
|
|
200
200
|
{ name: 'proposal', type: 'bytes32' }
|
|
@@ -203,7 +203,7 @@ export const cancelProposal2Types = {
|
|
|
203
203
|
|
|
204
204
|
export const voteTypes = {
|
|
205
205
|
Vote: [
|
|
206
|
-
{ name: 'from', type: '
|
|
206
|
+
{ name: 'from', type: 'string' },
|
|
207
207
|
{ name: 'space', type: 'string' },
|
|
208
208
|
{ name: 'timestamp', type: 'uint64' },
|
|
209
209
|
{ name: 'proposal', type: 'string' },
|
|
@@ -216,7 +216,7 @@ export const voteTypes = {
|
|
|
216
216
|
|
|
217
217
|
export const voteArrayTypes = {
|
|
218
218
|
Vote: [
|
|
219
|
-
{ name: 'from', type: '
|
|
219
|
+
{ name: 'from', type: 'string' },
|
|
220
220
|
{ name: 'space', type: 'string' },
|
|
221
221
|
{ name: 'timestamp', type: 'uint64' },
|
|
222
222
|
{ name: 'proposal', type: 'string' },
|
|
@@ -229,7 +229,7 @@ export const voteArrayTypes = {
|
|
|
229
229
|
|
|
230
230
|
export const voteStringTypes = {
|
|
231
231
|
Vote: [
|
|
232
|
-
{ name: 'from', type: '
|
|
232
|
+
{ name: 'from', type: 'string' },
|
|
233
233
|
{ name: 'space', type: 'string' },
|
|
234
234
|
{ name: 'timestamp', type: 'uint64' },
|
|
235
235
|
{ name: 'proposal', type: 'string' },
|
|
@@ -242,7 +242,7 @@ export const voteStringTypes = {
|
|
|
242
242
|
|
|
243
243
|
export const vote2Types = {
|
|
244
244
|
Vote: [
|
|
245
|
-
{ name: 'from', type: '
|
|
245
|
+
{ name: 'from', type: 'string' },
|
|
246
246
|
{ name: 'space', type: 'string' },
|
|
247
247
|
{ name: 'timestamp', type: 'uint64' },
|
|
248
248
|
{ name: 'proposal', type: 'bytes32' },
|
|
@@ -255,7 +255,7 @@ export const vote2Types = {
|
|
|
255
255
|
|
|
256
256
|
export const voteArray2Types = {
|
|
257
257
|
Vote: [
|
|
258
|
-
{ name: 'from', type: '
|
|
258
|
+
{ name: 'from', type: 'string' },
|
|
259
259
|
{ name: 'space', type: 'string' },
|
|
260
260
|
{ name: 'timestamp', type: 'uint64' },
|
|
261
261
|
{ name: 'proposal', type: 'bytes32' },
|
|
@@ -268,7 +268,7 @@ export const voteArray2Types = {
|
|
|
268
268
|
|
|
269
269
|
export const voteString2Types = {
|
|
270
270
|
Vote: [
|
|
271
|
-
{ name: 'from', type: '
|
|
271
|
+
{ name: 'from', type: 'string' },
|
|
272
272
|
{ name: 'space', type: 'string' },
|
|
273
273
|
{ name: 'timestamp', type: 'uint64' },
|
|
274
274
|
{ name: 'proposal', type: 'bytes32' },
|
package/src/utils.spec.js
CHANGED
|
@@ -504,37 +504,269 @@ describe('utils', () => {
|
|
|
504
504
|
});
|
|
505
505
|
|
|
506
506
|
describe('getFormattedAddress', () => {
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
507
|
+
describe('when explicitly passing an address type', () => {
|
|
508
|
+
describe('EVM type parsing', () => {
|
|
509
|
+
test('should return checksummed EVM address when given checksummed input', () => {
|
|
510
|
+
const address = '0x91FD2c8d24767db4Ece7069AA27832ffaf8590f3';
|
|
511
|
+
expect(getFormattedAddress(address, 'evm')).toEqual(
|
|
512
|
+
'0x91FD2c8d24767db4Ece7069AA27832ffaf8590f3'
|
|
513
|
+
);
|
|
514
|
+
});
|
|
513
515
|
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
});
|
|
516
|
+
test('should return checksummed EVM address when given lowercase input', () => {
|
|
517
|
+
const address = '0x91fd2c8d24767db4ece7069aa27832ffaf8590f3';
|
|
518
|
+
expect(getFormattedAddress(address, 'evm')).toEqual(
|
|
519
|
+
'0x91FD2c8d24767db4Ece7069AA27832ffaf8590f3'
|
|
520
|
+
);
|
|
521
|
+
});
|
|
521
522
|
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
523
|
+
test('should return checksummed EVM address when given uppercase input', () => {
|
|
524
|
+
const uppercaseAddress = '0x91FD2C8D24767DB4ECE7069AA27832FFAF8590F3';
|
|
525
|
+
expect(getFormattedAddress(uppercaseAddress, 'evm')).toEqual(
|
|
526
|
+
'0x91FD2c8d24767db4Ece7069AA27832ffaf8590f3'
|
|
527
|
+
);
|
|
528
|
+
});
|
|
528
529
|
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
530
|
+
test('should throw error when forcing EVM parsing on address with uppercase 0X prefix', () => {
|
|
531
|
+
const uppercaseHexPrefix =
|
|
532
|
+
'0X91FD2C8D24767DB4ECE7069AA27832FFAF8590F3';
|
|
533
|
+
expect(() => getFormattedAddress(uppercaseHexPrefix, 'evm')).toThrow(
|
|
534
|
+
'Invalid evm address: 0X91FD2C8D24767DB4ECE7069AA27832FFAF8590F3'
|
|
535
|
+
);
|
|
536
|
+
});
|
|
537
|
+
|
|
538
|
+
test('should throw error when forcing EVM parsing on invalid mixed case address', () => {
|
|
539
|
+
const invalidMixedCaseAddress =
|
|
540
|
+
'0x91Fd2C8d24767Db4eCe7069aA27832FfaF8590F3';
|
|
541
|
+
expect(() =>
|
|
542
|
+
getFormattedAddress(invalidMixedCaseAddress, 'evm')
|
|
543
|
+
).toThrow(
|
|
544
|
+
'Invalid evm address: 0x91Fd2C8d24767Db4eCe7069aA27832FfaF8590F3'
|
|
545
|
+
);
|
|
546
|
+
});
|
|
547
|
+
|
|
548
|
+
test('should throw error when address is not an EVM address', () => {
|
|
549
|
+
const address =
|
|
550
|
+
'0x2a0a8f3b6097e7a6bd7649deb30715323072a159c0e6b71b689bd245c146cc0';
|
|
551
|
+
expect(() => getFormattedAddress(address, 'evm')).toThrow(
|
|
552
|
+
'Invalid evm address: 0x2a0a8f3b6097e7a6bd7649deb30715323072a159c0e6b71b689bd245c146cc0'
|
|
553
|
+
);
|
|
554
|
+
});
|
|
555
|
+
});
|
|
556
|
+
|
|
557
|
+
describe('Starknet type parsing', () => {
|
|
558
|
+
test('should return padded and lowercased starknet address when given unpadded input', () => {
|
|
559
|
+
const address =
|
|
560
|
+
'0x2a0a8f3b6097e7a6bd7649deb30715323072a159c0e6b71b689bd245c146cc0';
|
|
561
|
+
expect(getFormattedAddress(address, 'starknet')).toEqual(
|
|
562
|
+
'0x02a0a8f3b6097e7a6bd7649deb30715323072a159c0e6b71b689bd245c146cc0'
|
|
563
|
+
);
|
|
564
|
+
});
|
|
565
|
+
|
|
566
|
+
test('should return padded and lowercased starknet address when given lowercase input', () => {
|
|
567
|
+
const address =
|
|
568
|
+
'0x02a0a8f3b6097e7a6bd7649deb30715323072a159c0e6b71b689bd245c146cc0';
|
|
569
|
+
expect(getFormattedAddress(address, 'starknet')).toEqual(
|
|
570
|
+
'0x02a0a8f3b6097e7a6bd7649deb30715323072a159c0e6b71b689bd245c146cc0'
|
|
571
|
+
);
|
|
572
|
+
});
|
|
573
|
+
|
|
574
|
+
test('should return padded and lowercased starknet address when given uppercase Starknet input', () => {
|
|
575
|
+
const uppercaseAddress =
|
|
576
|
+
'0x02A0A8F3B6097E7A6BD7649DEB30715323072A159C0E6B71B689BD245C146CC0';
|
|
577
|
+
expect(getFormattedAddress(uppercaseAddress, 'starknet')).toEqual(
|
|
578
|
+
'0x02a0a8f3b6097e7a6bd7649deb30715323072a159c0e6b71b689bd245c146cc0'
|
|
579
|
+
);
|
|
580
|
+
});
|
|
581
|
+
|
|
582
|
+
test('should return padded and lowercased starknet address when given checksum Starknet input', () => {
|
|
583
|
+
const checksumAddress =
|
|
584
|
+
'0x02a0a8F3B6097e7A6bd7649DEB30715323072A159c0E6B71B689Bd245c146cC0';
|
|
585
|
+
expect(getFormattedAddress(checksumAddress, 'starknet')).toEqual(
|
|
586
|
+
'0x02a0a8f3b6097e7a6bd7649deb30715323072a159c0e6b71b689bd245c146cc0'
|
|
587
|
+
);
|
|
588
|
+
});
|
|
589
|
+
|
|
590
|
+
test('should return padded and lowercased starknet address when given mixed case Starknet input', () => {
|
|
591
|
+
const mixedCaseAddress =
|
|
592
|
+
'0x02A0a8F3B6097e7A6bD7649DEB30715323072a159C0e6b71B689BD245c146Cc0';
|
|
593
|
+
expect(getFormattedAddress(mixedCaseAddress, 'starknet')).toEqual(
|
|
594
|
+
'0x02a0a8f3b6097e7a6bd7649deb30715323072a159c0e6b71b689bd245c146cc0'
|
|
595
|
+
);
|
|
596
|
+
});
|
|
597
|
+
|
|
598
|
+
test('should return EVM address as starknet address when explicitly formatted', () => {
|
|
599
|
+
const address = '0x91FD2c8d24767db4Ece7069AA27832ffaf8590f3';
|
|
600
|
+
expect(getFormattedAddress(address, 'starknet')).toEqual(
|
|
601
|
+
'0x00000000000000000000000091fd2c8d24767db4ece7069aa27832ffaf8590f3'
|
|
602
|
+
);
|
|
603
|
+
});
|
|
604
|
+
|
|
605
|
+
test('should throw error when given invalid Starknet address with explicit format', () => {
|
|
606
|
+
const invalidStarknetAddress = '0xinvalidstarknetaddresshere';
|
|
607
|
+
expect(() =>
|
|
608
|
+
getFormattedAddress(invalidStarknetAddress, 'starknet')
|
|
609
|
+
).toThrow('Invalid starknet address: 0xinvalidstarknetaddresshere');
|
|
610
|
+
});
|
|
611
|
+
});
|
|
532
612
|
});
|
|
533
613
|
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
'
|
|
537
|
-
|
|
614
|
+
describe('when not passing an address type', () => {
|
|
615
|
+
describe('EVM address auto-detection', () => {
|
|
616
|
+
test('should auto-detect and format valid 42-char lowercase EVM address', () => {
|
|
617
|
+
const address = '0x91fd2c8d24767db4ece7069aa27832ffaf8590f3';
|
|
618
|
+
expect(getFormattedAddress(address)).toEqual(
|
|
619
|
+
'0x91FD2c8d24767db4Ece7069AA27832ffaf8590f3'
|
|
620
|
+
);
|
|
621
|
+
});
|
|
622
|
+
|
|
623
|
+
test('should auto-detect and format valid 42-char uppercase EVM address', () => {
|
|
624
|
+
const address = '0x91FD2C8D24767DB4ECE7069AA27832FFAF8590F3';
|
|
625
|
+
expect(getFormattedAddress(address)).toEqual(
|
|
626
|
+
'0x91FD2c8d24767db4Ece7069AA27832ffaf8590f3'
|
|
627
|
+
);
|
|
628
|
+
});
|
|
629
|
+
|
|
630
|
+
test('should auto-detect and format valid 42-char checksummed EVM address', () => {
|
|
631
|
+
const address = '0x91FD2c8d24767db4Ece7069AA27832ffaf8590f3';
|
|
632
|
+
expect(getFormattedAddress(address)).toEqual(
|
|
633
|
+
'0x91FD2c8d24767db4Ece7069AA27832ffaf8590f3'
|
|
634
|
+
);
|
|
635
|
+
});
|
|
636
|
+
|
|
637
|
+
test('should throw error when auto-detecting invalid mixed case EVM address', () => {
|
|
638
|
+
const invalidMixedCaseAddress =
|
|
639
|
+
'0x91Fd2C8d24767Db4eCe7069aA27832FfaF8590F3';
|
|
640
|
+
expect(() => getFormattedAddress(invalidMixedCaseAddress)).toThrow(
|
|
641
|
+
'Invalid evm address: 0x91Fd2C8d24767Db4eCe7069aA27832FfaF8590F3'
|
|
642
|
+
);
|
|
643
|
+
});
|
|
644
|
+
|
|
645
|
+
test('should throw error when auto-detecting 42-char invalid hex address', () => {
|
|
646
|
+
const invalidHexAddress =
|
|
647
|
+
'0xgggggggggggggggggggggggggggggggggggggggg';
|
|
648
|
+
expect(() => getFormattedAddress(invalidHexAddress)).toThrow(
|
|
649
|
+
'Invalid evm address: 0xgggggggggggggggggggggggggggggggggggggggg'
|
|
650
|
+
);
|
|
651
|
+
});
|
|
652
|
+
|
|
653
|
+
test('should throw error when auto-detecting EVM address with uppercase 0X prefix', () => {
|
|
654
|
+
const uppercaseHexPrefix =
|
|
655
|
+
'0X91FD2C8D24767DB4ECE7069AA27832FFAF8590F3';
|
|
656
|
+
expect(() => getFormattedAddress(uppercaseHexPrefix)).toThrow(
|
|
657
|
+
'Invalid evm address: 0X91FD2C8D24767DB4ECE7069AA27832FFAF8590F3'
|
|
658
|
+
);
|
|
659
|
+
});
|
|
660
|
+
});
|
|
661
|
+
|
|
662
|
+
describe('Starknet address auto-detection', () => {
|
|
663
|
+
test('should auto-detect and format valid unpadded Starknet address', () => {
|
|
664
|
+
const address =
|
|
665
|
+
'0x2a0a8f3b6097e7a6bd7649deb30715323072a159c0e6b71b689bd245c146cc0';
|
|
666
|
+
expect(getFormattedAddress(address)).toEqual(
|
|
667
|
+
'0x02a0a8f3b6097e7a6bd7649deb30715323072a159c0e6b71b689bd245c146cc0'
|
|
668
|
+
);
|
|
669
|
+
});
|
|
670
|
+
|
|
671
|
+
test('should auto-detect and format valid padded Starknet address', () => {
|
|
672
|
+
const address =
|
|
673
|
+
'0x02a0a8f3b6097e7a6bd7649deb30715323072a159c0e6b71b689bd245c146cc0';
|
|
674
|
+
expect(getFormattedAddress(address)).toEqual(
|
|
675
|
+
'0x02a0a8f3b6097e7a6bd7649deb30715323072a159c0e6b71b689bd245c146cc0'
|
|
676
|
+
);
|
|
677
|
+
});
|
|
678
|
+
|
|
679
|
+
test('should auto-detect and format uppercase Starknet address', () => {
|
|
680
|
+
const address =
|
|
681
|
+
'0x02A0A8F3B6097E7A6BD7649DEB30715323072A159C0E6B71B689BD245C146CC0';
|
|
682
|
+
expect(getFormattedAddress(address)).toEqual(
|
|
683
|
+
'0x02a0a8f3b6097e7a6bd7649deb30715323072a159c0e6b71b689bd245c146cc0'
|
|
684
|
+
);
|
|
685
|
+
});
|
|
686
|
+
|
|
687
|
+
test('should return padded and lowercased address when input has uppercase 0X prefix', () => {
|
|
688
|
+
const fullyUppercaseAddress =
|
|
689
|
+
'0X02A0A8F3B6097E7A6BD7649DEB30715323072A159C0E6B71B689BD245C146CC0';
|
|
690
|
+
expect(getFormattedAddress(fullyUppercaseAddress)).toEqual(
|
|
691
|
+
'0x02a0a8f3b6097e7a6bd7649deb30715323072a159c0e6b71b689bd245c146cc0'
|
|
692
|
+
);
|
|
693
|
+
});
|
|
694
|
+
|
|
695
|
+
test('should return padded and lowercased address when given short input', () => {
|
|
696
|
+
const address = '0x1';
|
|
697
|
+
expect(getFormattedAddress(address)).toEqual(
|
|
698
|
+
'0x0000000000000000000000000000000000000000000000000000000000000001'
|
|
699
|
+
);
|
|
700
|
+
});
|
|
701
|
+
|
|
702
|
+
test('should auto-detect actual 41-char address as Starknet', () => {
|
|
703
|
+
const address = '0x123456789012345678901234567890123456789';
|
|
704
|
+
expect(getFormattedAddress(address)).toEqual(
|
|
705
|
+
'0x0000000000000000000000000123456789012345678901234567890123456789'
|
|
706
|
+
);
|
|
707
|
+
});
|
|
708
|
+
|
|
709
|
+
test('should auto-detect 43+ char address as Starknet', () => {
|
|
710
|
+
const address = '0x123456789012345678901234567890123456789012';
|
|
711
|
+
expect(getFormattedAddress(address)).toEqual(
|
|
712
|
+
'0x0000000000000000000000123456789012345678901234567890123456789012'
|
|
713
|
+
);
|
|
714
|
+
});
|
|
715
|
+
});
|
|
716
|
+
|
|
717
|
+
describe('Invalid address format', () => {
|
|
718
|
+
test('should throw error when passing invalid format argument', () => {
|
|
719
|
+
const validAddress = '0x91fd2c8d24767db4ece7069aa27832ffaf8590f3';
|
|
720
|
+
expect(() => getFormattedAddress(validAddress, 'invalid')).toThrow(
|
|
721
|
+
'Invalid invalid address: 0x91fd2c8d24767db4ece7069aa27832ffaf8590f3'
|
|
722
|
+
);
|
|
723
|
+
});
|
|
724
|
+
|
|
725
|
+
test('should treat undefined format parameter as auto-detection', () => {
|
|
726
|
+
const evmAddress = '0x91fd2c8d24767db4ece7069aa27832ffaf8590f3';
|
|
727
|
+
expect(getFormattedAddress(evmAddress, undefined)).toEqual(
|
|
728
|
+
'0x91FD2c8d24767db4Ece7069AA27832ffaf8590f3'
|
|
729
|
+
);
|
|
730
|
+
});
|
|
731
|
+
|
|
732
|
+
test('should throw error when parsing invalid string', () => {
|
|
733
|
+
const invalidString = 'hello';
|
|
734
|
+
expect(() => getFormattedAddress(invalidString)).toThrow(
|
|
735
|
+
'Invalid address: hello'
|
|
736
|
+
);
|
|
737
|
+
});
|
|
738
|
+
|
|
739
|
+
test('should throw error when parsing empty string', () => {
|
|
740
|
+
const emptyString = '';
|
|
741
|
+
expect(() => getFormattedAddress(emptyString)).toThrow(
|
|
742
|
+
'Invalid address: '
|
|
743
|
+
);
|
|
744
|
+
});
|
|
745
|
+
|
|
746
|
+
test('should throw error when parsing null input', () => {
|
|
747
|
+
expect(() => getFormattedAddress(null)).toThrow(
|
|
748
|
+
'Invalid address: null'
|
|
749
|
+
);
|
|
750
|
+
});
|
|
751
|
+
|
|
752
|
+
test('should throw error when parsing undefined input', () => {
|
|
753
|
+
expect(() => getFormattedAddress(undefined)).toThrow(
|
|
754
|
+
'Invalid address: undefined'
|
|
755
|
+
);
|
|
756
|
+
});
|
|
757
|
+
|
|
758
|
+
test('should throw error when parsing number input', () => {
|
|
759
|
+
expect(() => getFormattedAddress(123)).toThrow(
|
|
760
|
+
'Invalid address: 123'
|
|
761
|
+
);
|
|
762
|
+
});
|
|
763
|
+
|
|
764
|
+
test('should throw error when parsing object input', () => {
|
|
765
|
+
expect(() => getFormattedAddress({})).toThrow(
|
|
766
|
+
'Invalid address: [object Object]'
|
|
767
|
+
);
|
|
768
|
+
});
|
|
769
|
+
});
|
|
538
770
|
});
|
|
539
771
|
});
|
|
540
772
|
|
package/src/utils.ts
CHANGED
|
@@ -828,13 +828,20 @@ export function isEvmAddress(address: string): boolean {
|
|
|
828
828
|
|
|
829
829
|
export function getFormattedAddress(
|
|
830
830
|
address: string,
|
|
831
|
-
format
|
|
831
|
+
format?: 'evm' | 'starknet'
|
|
832
832
|
): string {
|
|
833
|
-
if (
|
|
834
|
-
|
|
833
|
+
if (typeof address !== 'string' || !/^0[xX]/.test(address)) {
|
|
834
|
+
throw new Error(`Invalid address: ${address}`);
|
|
835
|
+
}
|
|
836
|
+
|
|
837
|
+
const addressType = format ?? (address.length === 42 ? 'evm' : 'starknet');
|
|
838
|
+
|
|
839
|
+
if (addressType === 'evm' && isEvmAddress(address))
|
|
840
|
+
return getAddress(address);
|
|
841
|
+
if (addressType === 'starknet' && isStarknetAddress(address))
|
|
835
842
|
return validateAndParseAddress(address);
|
|
836
843
|
|
|
837
|
-
throw new Error(`Invalid address: ${address}`);
|
|
844
|
+
throw new Error(`Invalid ${addressType} address: ${address}`);
|
|
838
845
|
}
|
|
839
846
|
|
|
840
847
|
function inputError(message: string) {
|