@snapshot-labs/snapshot.js 0.12.0-beta.5 → 0.12.0-beta.7
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 +26 -17
- package/dist/snapshot.esm.js +26 -17
- package/dist/snapshot.min.js +1 -1
- package/dist/src/utils.d.ts +1 -1
- package/package.json +4 -3
- package/src/networks.json +6 -6
- package/src/sign/hashedTypes.json +2 -1
- package/src/utils.spec.js +85 -1
- package/src/utils.ts +25 -15
- package/src/verify/starknet.spec.ts +12 -0
package/dist/src/utils.d.ts
CHANGED
|
@@ -28,7 +28,7 @@ interface validateSchemaOptions {
|
|
|
28
28
|
spaceType?: string;
|
|
29
29
|
}
|
|
30
30
|
export declare function validateSchema(schema: any, data: any, options?: validateSchemaOptions): true | import("ajv").ErrorObject<string, Record<string, any>, unknown>[] | null | undefined;
|
|
31
|
-
export declare function getEnsTextRecord(ens: string, record: string, network?: string, options?: any): Promise<
|
|
31
|
+
export declare function getEnsTextRecord(ens: string, record: string, network?: string, options?: any): Promise<string | null>;
|
|
32
32
|
export declare function getSpaceUri(id: string, network?: string, options?: any): Promise<string | null>;
|
|
33
33
|
export declare function getEnsOwner(ens: string, network?: string, options?: any): Promise<string | null>;
|
|
34
34
|
export declare function getSpaceController(id: string, network?: string, options?: any): Promise<string | null>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@snapshot-labs/snapshot.js",
|
|
3
|
-
"version": "0.12.0-beta.
|
|
3
|
+
"version": "0.12.0-beta.7",
|
|
4
4
|
"repository": "snapshot-labs/snapshot.js",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"main": "dist/snapshot.cjs.js",
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
"rollup-plugin-terser": "^7.0.0",
|
|
47
47
|
"rollup-plugin-typescript2": "^0.27.0",
|
|
48
48
|
"ts-node": "^10.9.2",
|
|
49
|
-
"typescript": "^5",
|
|
49
|
+
"typescript": "^5.0.0",
|
|
50
50
|
"vitest": "^0.33.0"
|
|
51
51
|
},
|
|
52
52
|
"scripts": {
|
|
@@ -55,7 +55,8 @@
|
|
|
55
55
|
"test": "vitest",
|
|
56
56
|
"test:once": "vitest run",
|
|
57
57
|
"dev": "rollup -c -w",
|
|
58
|
-
"lint": "eslint . --ext .ts
|
|
58
|
+
"lint": "eslint . --ext .ts",
|
|
59
|
+
"lint:fix": "yarn lint --fix",
|
|
59
60
|
"typecheck": "tsc --noEmit",
|
|
60
61
|
"prepublishOnly": "yarn build"
|
|
61
62
|
},
|
package/src/networks.json
CHANGED
|
@@ -151,7 +151,7 @@
|
|
|
151
151
|
},
|
|
152
152
|
"56": {
|
|
153
153
|
"key": "56",
|
|
154
|
-
"name": "
|
|
154
|
+
"name": "BNB Smart Chain",
|
|
155
155
|
"shortName": "BSC",
|
|
156
156
|
"chainId": 56,
|
|
157
157
|
"network": "mainnet",
|
|
@@ -168,7 +168,7 @@
|
|
|
168
168
|
"url": "https://bscscan.com"
|
|
169
169
|
},
|
|
170
170
|
"start": 461230,
|
|
171
|
-
"logo": "ipfs://
|
|
171
|
+
"logo": "ipfs://bafkreibll4la7wqerzs7zwxjne2j7ayynbg2wlenemssoahxxj5rbt6c64"
|
|
172
172
|
},
|
|
173
173
|
"61": {
|
|
174
174
|
"key": "61",
|
|
@@ -254,7 +254,7 @@
|
|
|
254
254
|
},
|
|
255
255
|
"97": {
|
|
256
256
|
"key": "97",
|
|
257
|
-
"name": "
|
|
257
|
+
"name": "BNB Smart Chain Testnet",
|
|
258
258
|
"shortName": "BSC Testnet",
|
|
259
259
|
"chainId": 97,
|
|
260
260
|
"network": "testnet",
|
|
@@ -268,7 +268,7 @@
|
|
|
268
268
|
"url": "https://testnet.bscscan.com"
|
|
269
269
|
},
|
|
270
270
|
"start": 3599656,
|
|
271
|
-
"logo": "ipfs://
|
|
271
|
+
"logo": "ipfs://bafkreibll4la7wqerzs7zwxjne2j7ayynbg2wlenemssoahxxj5rbt6c64"
|
|
272
272
|
},
|
|
273
273
|
"100": {
|
|
274
274
|
"key": "100",
|
|
@@ -1408,7 +1408,7 @@
|
|
|
1408
1408
|
"url": "https://blastscan.io"
|
|
1409
1409
|
},
|
|
1410
1410
|
"start": 88189,
|
|
1411
|
-
"logo": "ipfs://
|
|
1411
|
+
"logo": "ipfs://bafkreicqhrimt2zyp2kvhmbpvffxlmxovkg5vw6zkissyzibcfy45kbvrm"
|
|
1412
1412
|
},
|
|
1413
1413
|
"84532": {
|
|
1414
1414
|
"key": "84532",
|
|
@@ -1622,4 +1622,4 @@
|
|
|
1622
1622
|
"start": 7521509,
|
|
1623
1623
|
"logo": "ipfs://QmNnGPr1CNvj12SSGzKARtUHv9FyEfE5nES73U4vBWQSJL"
|
|
1624
1624
|
}
|
|
1625
|
-
}
|
|
1625
|
+
}
|
|
@@ -59,5 +59,6 @@
|
|
|
59
59
|
"8ea9074bff3a30cb61f4f0f0f142c9335c6be828feba0571a45de3f1fd0319c0": "alias",
|
|
60
60
|
"42f8858a21d4aa232721cb97074851e729829ea362b88bb21f3879899663b586": "follow",
|
|
61
61
|
"2bb75450e28b06f259ea764cd669de6bde0ba70ce729b0ff05ab9df56e0ff21d": "unfollow",
|
|
62
|
-
"2ffbebcbd22ef48fd2f4a1182ff1feda7795b57689bd6f0dd73c89e925e7fefb": "profile"
|
|
62
|
+
"2ffbebcbd22ef48fd2f4a1182ff1feda7795b57689bd6f0dd73c89e925e7fefb": "profile",
|
|
63
|
+
"4288d50b713081aae77d60d596d75864bff7acf7791a00183401e58658ee9da5": "statement"
|
|
63
64
|
}
|
package/src/utils.spec.js
CHANGED
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
import { describe, test, expect, vi, afterEach } from 'vitest';
|
|
2
2
|
import * as crossFetch from 'cross-fetch';
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
validate,
|
|
5
|
+
validateSchema,
|
|
6
|
+
getScores,
|
|
7
|
+
getVp,
|
|
8
|
+
getFormattedAddress
|
|
9
|
+
} from './utils';
|
|
4
10
|
|
|
5
11
|
vi.mock('cross-fetch', async () => {
|
|
6
12
|
const actual = await vi.importActual('cross-fetch');
|
|
@@ -527,4 +533,82 @@ describe('utils', () => {
|
|
|
527
533
|
expect(() => getFormattedAddress(address, 'evm')).toThrow();
|
|
528
534
|
});
|
|
529
535
|
});
|
|
536
|
+
|
|
537
|
+
describe('address validation', () => {
|
|
538
|
+
const evmSchema = {
|
|
539
|
+
$schema: 'http://json-schema.org/draft-07/schema#',
|
|
540
|
+
$ref: '#/definitions/Envelope',
|
|
541
|
+
definitions: {
|
|
542
|
+
Envelope: {
|
|
543
|
+
type: 'object',
|
|
544
|
+
properties: {
|
|
545
|
+
address: {
|
|
546
|
+
type: 'string',
|
|
547
|
+
format: 'address'
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
};
|
|
553
|
+
|
|
554
|
+
const starknetSchema = {
|
|
555
|
+
$schema: 'http://json-schema.org/draft-07/schema#',
|
|
556
|
+
$ref: '#/definitions/Envelope',
|
|
557
|
+
definitions: {
|
|
558
|
+
Envelope: {
|
|
559
|
+
type: 'object',
|
|
560
|
+
properties: {
|
|
561
|
+
address: {
|
|
562
|
+
type: 'string',
|
|
563
|
+
format: 'starknetAddress'
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
};
|
|
569
|
+
|
|
570
|
+
test('should return true on checksummed EVM address', async () => {
|
|
571
|
+
const result = validateSchema(evmSchema, {
|
|
572
|
+
address: '0x91FD2c8d24767db4Ece7069AA27832ffaf8590f3'
|
|
573
|
+
});
|
|
574
|
+
expect(result).toBe(true);
|
|
575
|
+
});
|
|
576
|
+
|
|
577
|
+
test('should return an error on lowercase EVM address', async () => {
|
|
578
|
+
const result = validateSchema(evmSchema, {
|
|
579
|
+
address: '0x91FD2c8d24767db4Ece7069AA27832ffaf8590f3'.toLowerCase()
|
|
580
|
+
});
|
|
581
|
+
expect(result).not.toBe(true);
|
|
582
|
+
});
|
|
583
|
+
|
|
584
|
+
test('should return an error on empty address', async () => {
|
|
585
|
+
const result = validateSchema(evmSchema, {
|
|
586
|
+
address: ''
|
|
587
|
+
});
|
|
588
|
+
expect(result).not.toBe(true);
|
|
589
|
+
});
|
|
590
|
+
|
|
591
|
+
test('should return true on lowercase padded starknet address', async () => {
|
|
592
|
+
const result = validateSchema(starknetSchema, {
|
|
593
|
+
address:
|
|
594
|
+
'0x02a0a8f3b6097e7a6bd7649deb30715323072a159c0e6b71b689bd245c146cc0'
|
|
595
|
+
});
|
|
596
|
+
expect(result).toBe(true);
|
|
597
|
+
});
|
|
598
|
+
|
|
599
|
+
test('should return an error on non-padded starknet address', async () => {
|
|
600
|
+
const result = validateSchema(starknetSchema, {
|
|
601
|
+
address:
|
|
602
|
+
'0x2a0a8f3b6097e7a6bd7649deb30715323072a159c0e6b71b689bd245c146cc0'
|
|
603
|
+
});
|
|
604
|
+
expect(result).not.toBe(true);
|
|
605
|
+
});
|
|
606
|
+
|
|
607
|
+
test('should return an error on empty starknet address', async () => {
|
|
608
|
+
const result = validateSchema(starknetSchema, {
|
|
609
|
+
address: ''
|
|
610
|
+
});
|
|
611
|
+
expect(result).not.toBe(true);
|
|
612
|
+
});
|
|
613
|
+
});
|
|
530
614
|
});
|
package/src/utils.ts
CHANGED
|
@@ -30,8 +30,10 @@ interface Strategy {
|
|
|
30
30
|
params: any;
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
const
|
|
34
|
-
|
|
33
|
+
const ENS_REGISTRY = '0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e';
|
|
34
|
+
const ENS_ABI = [
|
|
35
|
+
'function text(bytes32 node, string calldata key) external view returns (string memory)',
|
|
36
|
+
'function resolver(bytes32 node) view returns (address)' // ENS registry ABI
|
|
35
37
|
];
|
|
36
38
|
const EMPTY_ADDRESS = '0x0000000000000000000000000000000000000000';
|
|
37
39
|
|
|
@@ -90,7 +92,7 @@ addErrors(ajv);
|
|
|
90
92
|
ajv.addFormat('address', {
|
|
91
93
|
validate: (value: string) => {
|
|
92
94
|
try {
|
|
93
|
-
return
|
|
95
|
+
return value === getAddress(value);
|
|
94
96
|
} catch (e: any) {
|
|
95
97
|
return false;
|
|
96
98
|
}
|
|
@@ -100,7 +102,7 @@ ajv.addFormat('address', {
|
|
|
100
102
|
ajv.addFormat('starknetAddress', {
|
|
101
103
|
validate: (value: string) => {
|
|
102
104
|
try {
|
|
103
|
-
return
|
|
105
|
+
return validateAndParseAddress(value) === value;
|
|
104
106
|
} catch (e: any) {
|
|
105
107
|
return false;
|
|
106
108
|
}
|
|
@@ -536,25 +538,34 @@ export async function getEnsTextRecord(
|
|
|
536
538
|
options: any = {}
|
|
537
539
|
) {
|
|
538
540
|
const {
|
|
539
|
-
ensResolvers
|
|
541
|
+
ensResolvers = networks[network]?.ensResolvers ||
|
|
542
|
+
networks['1'].ensResolvers,
|
|
540
543
|
broviderUrl,
|
|
541
544
|
...multicallOptions
|
|
542
545
|
} = options;
|
|
543
|
-
|
|
544
|
-
ensResolversOpt ||
|
|
545
|
-
networks[network].ensResolvers ||
|
|
546
|
-
networks['1'].ensResolvers;
|
|
546
|
+
|
|
547
547
|
const ensHash = namehash(ensNormalize(ens));
|
|
548
548
|
const provider = getProvider(network, { broviderUrl });
|
|
549
549
|
|
|
550
|
-
const
|
|
550
|
+
const calls = [
|
|
551
|
+
[ENS_REGISTRY, 'resolver', [ensHash]], // Query for resolver from registry
|
|
552
|
+
...ensResolvers.map((address: string) => [
|
|
553
|
+
address,
|
|
554
|
+
'text',
|
|
555
|
+
[ensHash, record]
|
|
556
|
+
]) // Query for text record from each resolver
|
|
557
|
+
];
|
|
558
|
+
|
|
559
|
+
const [[resolverAddress], ...textRecords]: string[][] = await multicall(
|
|
551
560
|
network,
|
|
552
561
|
provider,
|
|
553
|
-
|
|
554
|
-
|
|
562
|
+
ENS_ABI,
|
|
563
|
+
calls,
|
|
555
564
|
multicallOptions
|
|
556
565
|
);
|
|
557
|
-
|
|
566
|
+
|
|
567
|
+
const resolverIndex = ensResolvers.indexOf(resolverAddress);
|
|
568
|
+
return resolverIndex !== -1 ? textRecords[resolverIndex]?.[0] : null;
|
|
558
569
|
}
|
|
559
570
|
|
|
560
571
|
export async function getSpaceUri(
|
|
@@ -575,10 +586,9 @@ export async function getEnsOwner(
|
|
|
575
586
|
network = '1',
|
|
576
587
|
options: any = {}
|
|
577
588
|
): Promise<string | null> {
|
|
578
|
-
const registryAddress = '0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e';
|
|
579
589
|
const provider = getProvider(network, options);
|
|
580
590
|
const ensRegistry = new Contract(
|
|
581
|
-
|
|
591
|
+
ENS_REGISTRY,
|
|
582
592
|
['function owner(bytes32) view returns (address)'],
|
|
583
593
|
provider
|
|
584
594
|
);
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { test, expect, describe } from 'vitest';
|
|
2
2
|
import starknetMessage from '../../test/fixtures/starknet/message-alias.json';
|
|
3
3
|
import verify, { getHash } from './starknet';
|
|
4
|
+
import { validateAndParseAddress } from 'starknet';
|
|
4
5
|
|
|
5
6
|
describe('verify/starknet', () => {
|
|
6
7
|
describe('getHash()', () => {
|
|
@@ -31,6 +32,17 @@ describe('verify/starknet', () => {
|
|
|
31
32
|
).resolves.toBe(true);
|
|
32
33
|
});
|
|
33
34
|
|
|
35
|
+
test('should return true if the signature is valid with a padded address', () => {
|
|
36
|
+
expect(
|
|
37
|
+
verify(
|
|
38
|
+
validateAndParseAddress(starknetMessage.address),
|
|
39
|
+
starknetMessage.sig,
|
|
40
|
+
starknetMessage.data,
|
|
41
|
+
'SN_SEPOLIA'
|
|
42
|
+
)
|
|
43
|
+
).resolves.toBe(true);
|
|
44
|
+
});
|
|
45
|
+
|
|
34
46
|
test('should throw an error if message is on wrong network', () => {
|
|
35
47
|
expect(
|
|
36
48
|
verify(
|