@snapshot-labs/snapshot.js 0.13.1 → 0.14.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 +499 -324
- package/dist/snapshot.esm.js +500 -325
- package/dist/snapshot.min.js +21 -21
- package/dist/src/index.d.ts +4 -20
- package/dist/src/multicall/evm.d.ts +4 -0
- package/dist/src/multicall/index.d.ts +3 -0
- package/dist/src/multicall/multicaller.d.ts +15 -0
- package/dist/src/multicall/starknet.d.ts +2 -0
- package/dist/src/schemas/index.d.ts +2 -18
- package/dist/src/utils/provider.d.ts +5 -6
- package/dist/src/utils.d.ts +1 -2
- package/package.json +1 -1
- package/src/multicall/evm.ts +48 -0
- package/src/multicall/index.ts +52 -0
- package/src/{utils → multicall}/multicaller.ts +13 -8
- package/src/multicall/starknet.ts +154 -0
- package/src/networks.json +30 -1
- package/src/schemas/space.json +3 -13
- package/src/sign/hashedTypes.json +2 -1
- package/src/sign/types.ts +1 -1
- package/src/utils/provider.ts +91 -44
- package/src/utils.ts +3 -74
- package/dist/src/utils/multicaller.d.ts +0 -12
package/dist/snapshot.esm.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import fetch from 'cross-fetch';
|
|
2
|
-
import { AbiCoder, Interface } from '@ethersproject/abi';
|
|
3
2
|
import { Contract as Contract$1 } from '@ethersproject/contracts';
|
|
4
3
|
import { isAddress, getAddress } from '@ethersproject/address';
|
|
5
4
|
import { parseUnits } from '@ethersproject/units';
|
|
@@ -8,12 +7,13 @@ import { jsonToGraphQLQuery } from 'json-to-graphql-query';
|
|
|
8
7
|
import Ajv from 'ajv';
|
|
9
8
|
import addFormats from 'ajv-formats';
|
|
10
9
|
import addErrors from 'ajv-errors';
|
|
11
|
-
import set from 'lodash.set';
|
|
12
10
|
import { StaticJsonRpcProvider } from '@ethersproject/providers';
|
|
11
|
+
import { RpcProvider, Contract, typedData, transaction, uint256, shortString, num, constants as constants$1, validateAndParseAddress } from 'starknet';
|
|
13
12
|
import { hexlify, concat, arrayify } from '@ethersproject/bytes';
|
|
14
|
-
import { Contract, RpcProvider, typedData, validateAndParseAddress } from 'starknet';
|
|
15
13
|
import { BigNumber } from '@ethersproject/bignumber';
|
|
16
14
|
import { verifyTypedData } from '@ethersproject/wallet';
|
|
15
|
+
import { AbiCoder, Interface } from '@ethersproject/abi';
|
|
16
|
+
import set from 'lodash.set';
|
|
17
17
|
|
|
18
18
|
/*! *****************************************************************************
|
|
19
19
|
Copyright (c) Microsoft Corporation. All rights reserved.
|
|
@@ -97,7 +97,7 @@ const updateProposalTypes = {
|
|
|
97
97
|
};
|
|
98
98
|
const flagProposalTypes = {
|
|
99
99
|
FlagProposal: [
|
|
100
|
-
{ name: 'from', type: '
|
|
100
|
+
{ name: 'from', type: 'string' },
|
|
101
101
|
{ name: 'space', type: 'string' },
|
|
102
102
|
{ name: 'proposal', type: 'string' },
|
|
103
103
|
{ name: 'timestamp', type: 'uint64' }
|
|
@@ -273,33 +273,6 @@ var constants = {
|
|
|
273
273
|
local: local
|
|
274
274
|
};
|
|
275
275
|
|
|
276
|
-
class Multicaller {
|
|
277
|
-
constructor(network, provider, abi, options) {
|
|
278
|
-
this.options = {};
|
|
279
|
-
this.calls = [];
|
|
280
|
-
this.paths = [];
|
|
281
|
-
this.network = network;
|
|
282
|
-
this.provider = provider;
|
|
283
|
-
this.abi = abi;
|
|
284
|
-
this.options = options || {};
|
|
285
|
-
}
|
|
286
|
-
call(path, address, fn, params) {
|
|
287
|
-
this.calls.push([address, fn, params]);
|
|
288
|
-
this.paths.push(path);
|
|
289
|
-
return this;
|
|
290
|
-
}
|
|
291
|
-
execute(from) {
|
|
292
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
293
|
-
const obj = from || {};
|
|
294
|
-
const result = yield multicall(this.network, this.provider, this.abi, this.calls, this.options);
|
|
295
|
-
result.forEach((r, i) => set(obj, this.paths[i], r.length > 1 ? r : r[0]));
|
|
296
|
-
this.calls = [];
|
|
297
|
-
this.paths = [];
|
|
298
|
-
return obj;
|
|
299
|
-
});
|
|
300
|
-
}
|
|
301
|
-
}
|
|
302
|
-
|
|
303
276
|
let cache = {};
|
|
304
277
|
let expirationTime = 0;
|
|
305
278
|
function getSnapshots(network_1, snapshot_1, provider_1, networks_1) {
|
|
@@ -347,213 +320,6 @@ function getSnapshots(network_1, snapshot_1, provider_1, networks_1) {
|
|
|
347
320
|
});
|
|
348
321
|
}
|
|
349
322
|
|
|
350
|
-
const providers = {};
|
|
351
|
-
const DEFAULT_BROVIDER_URL = 'https://rpc.snapshot.org';
|
|
352
|
-
const DEFAULT_TIMEOUT = 25000;
|
|
353
|
-
function getProvider(network, { broviderUrl = DEFAULT_BROVIDER_URL, timeout = DEFAULT_TIMEOUT } = {}) {
|
|
354
|
-
const url = `${broviderUrl}/${network}`;
|
|
355
|
-
if (!providers[network])
|
|
356
|
-
providers[network] = new StaticJsonRpcProvider({
|
|
357
|
-
url,
|
|
358
|
-
timeout,
|
|
359
|
-
allowGzip: true
|
|
360
|
-
}, Number(network));
|
|
361
|
-
return providers[network];
|
|
362
|
-
}
|
|
363
|
-
|
|
364
|
-
function signMessage(web3, msg, address) {
|
|
365
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
366
|
-
msg = hexlify(new Buffer(msg, 'utf8'));
|
|
367
|
-
return yield web3.send('personal_sign', [msg, address]);
|
|
368
|
-
});
|
|
369
|
-
}
|
|
370
|
-
function getBlockNumber(provider) {
|
|
371
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
372
|
-
try {
|
|
373
|
-
const blockNumber = yield provider.getBlockNumber();
|
|
374
|
-
return parseInt(blockNumber);
|
|
375
|
-
}
|
|
376
|
-
catch (e) {
|
|
377
|
-
return Promise.reject();
|
|
378
|
-
}
|
|
379
|
-
});
|
|
380
|
-
}
|
|
381
|
-
|
|
382
|
-
const RPC_URLS = {
|
|
383
|
-
SN_MAIN: 'https://starknet-mainnet.public.blastapi.io',
|
|
384
|
-
SN_SEPOLIA: 'https://starknet-sepolia.public.blastapi.io'
|
|
385
|
-
};
|
|
386
|
-
const ABI = [
|
|
387
|
-
{
|
|
388
|
-
name: 'argent::common::account::IAccount',
|
|
389
|
-
type: 'interface',
|
|
390
|
-
items: [
|
|
391
|
-
{
|
|
392
|
-
name: 'is_valid_signature',
|
|
393
|
-
type: 'function',
|
|
394
|
-
inputs: [
|
|
395
|
-
{
|
|
396
|
-
name: 'hash',
|
|
397
|
-
type: 'core::felt252'
|
|
398
|
-
},
|
|
399
|
-
{
|
|
400
|
-
name: 'signature',
|
|
401
|
-
type: 'core::array::Array::<core::felt252>'
|
|
402
|
-
}
|
|
403
|
-
],
|
|
404
|
-
outputs: [
|
|
405
|
-
{
|
|
406
|
-
type: 'core::felt252'
|
|
407
|
-
}
|
|
408
|
-
],
|
|
409
|
-
state_mutability: 'view'
|
|
410
|
-
}
|
|
411
|
-
]
|
|
412
|
-
}
|
|
413
|
-
];
|
|
414
|
-
function getProvider$1(network, options) {
|
|
415
|
-
var _a;
|
|
416
|
-
if (!RPC_URLS[network])
|
|
417
|
-
throw new Error('Invalid network');
|
|
418
|
-
return new RpcProvider({
|
|
419
|
-
nodeUrl: (_a = options === null || options === void 0 ? void 0 : options.broviderUrl) !== null && _a !== void 0 ? _a : RPC_URLS[network]
|
|
420
|
-
});
|
|
421
|
-
}
|
|
422
|
-
function isStarknetMessage(data) {
|
|
423
|
-
return !!data.primaryType && !!data.types.StarkNetDomain;
|
|
424
|
-
}
|
|
425
|
-
function getHash(data, address) {
|
|
426
|
-
const { domain, types, primaryType, message } = data;
|
|
427
|
-
return typedData.getMessageHash({ types, primaryType, domain, message }, address);
|
|
428
|
-
}
|
|
429
|
-
function verify(address_1, sig_1, data_1) {
|
|
430
|
-
return __awaiter(this, arguments, void 0, function* (address, sig, data, network = 'SN_MAIN', options = {}) {
|
|
431
|
-
try {
|
|
432
|
-
const contractAccount = new Contract(ABI, address, getProvider$1(network, options));
|
|
433
|
-
if (sig.length < 2) {
|
|
434
|
-
throw new Error('Invalid signature format');
|
|
435
|
-
}
|
|
436
|
-
const result = yield contractAccount.is_valid_signature(getHash(data, address), sig.slice(-2));
|
|
437
|
-
return BigNumber.from(result).eq(BigNumber.from('370462705988'));
|
|
438
|
-
}
|
|
439
|
-
catch (e) {
|
|
440
|
-
if (e.message.includes('Contract not found')) {
|
|
441
|
-
throw new Error('Contract not deployed');
|
|
442
|
-
}
|
|
443
|
-
throw e;
|
|
444
|
-
}
|
|
445
|
-
});
|
|
446
|
-
}
|
|
447
|
-
|
|
448
|
-
var starknet = /*#__PURE__*/Object.freeze({
|
|
449
|
-
__proto__: null,
|
|
450
|
-
isStarknetMessage: isStarknetMessage,
|
|
451
|
-
getHash: getHash,
|
|
452
|
-
'default': verify
|
|
453
|
-
});
|
|
454
|
-
|
|
455
|
-
const ERC6492_DETECTION_SUFFIX = '6492649264926492649264926492649264926492649264926492649264926492';
|
|
456
|
-
function isEqual(a, b) {
|
|
457
|
-
return a.toLowerCase() === b.toLowerCase();
|
|
458
|
-
}
|
|
459
|
-
function getHash$1(data) {
|
|
460
|
-
const { domain, types, message } = data;
|
|
461
|
-
return _TypedDataEncoder.hash(domain, types, message);
|
|
462
|
-
}
|
|
463
|
-
function verify$1(address_1, sig_1, data_1) {
|
|
464
|
-
return __awaiter(this, arguments, void 0, function* (address, sig, data, network = '1', options = {}) {
|
|
465
|
-
const { domain, types, message } = data;
|
|
466
|
-
try {
|
|
467
|
-
const recoverAddress = verifyTypedData(domain, types, message, sig);
|
|
468
|
-
if (isEqual(address, recoverAddress))
|
|
469
|
-
return true;
|
|
470
|
-
}
|
|
471
|
-
catch (e) { }
|
|
472
|
-
const provider = getProvider(network, options);
|
|
473
|
-
const hash = getHash$1(data);
|
|
474
|
-
// Handle EIP-6492
|
|
475
|
-
// https://eips.ethereum.org/EIPS/eip-6492
|
|
476
|
-
//
|
|
477
|
-
// We can actually replace verifyTypedData and verifyDefault with the following code,
|
|
478
|
-
// but https://github.com/AmbireTech/signature-validator/blob/main/contracts/DeploylessUniversalSigValidator.sol
|
|
479
|
-
// also can send an extra network request to the provider. (with verifyTypedData we don't send any extra request)
|
|
480
|
-
//
|
|
481
|
-
if (sig.endsWith(ERC6492_DETECTION_SUFFIX)) {
|
|
482
|
-
try {
|
|
483
|
-
return ('0x01' ===
|
|
484
|
-
(yield provider.call({
|
|
485
|
-
data: concat([
|
|
486
|
-
'0x60806040523480156200001157600080fd5b50604051620007003803806200070083398101604081905262000034916200056f565b6000620000438484846200004f565b9050806000526001601ff35b600080846001600160a01b0316803b806020016040519081016040528181526000908060200190933c90507f6492649264926492649264926492649264926492649264926492649264926492620000a68462000451565b036200021f57600060608085806020019051810190620000c79190620005ce565b8651929550909350915060000362000192576000836001600160a01b031683604051620000f5919062000643565b6000604051808303816000865af19150503d806000811462000134576040519150601f19603f3d011682016040523d82523d6000602084013e62000139565b606091505b5050905080620001905760405162461bcd60e51b815260206004820152601e60248201527f5369676e617475726556616c696461746f723a206465706c6f796d656e74000060448201526064015b60405180910390fd5b505b604051630b135d3f60e11b808252906001600160a01b038a1690631626ba7e90620001c4908b90869060040162000661565b602060405180830381865afa158015620001e2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200020891906200069d565b6001600160e01b031916149450505050506200044a565b805115620002b157604051630b135d3f60e11b808252906001600160a01b03871690631626ba7e9062000259908890889060040162000661565b602060405180830381865afa15801562000277573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200029d91906200069d565b6001600160e01b031916149150506200044a565b8251604114620003195760405162461bcd60e51b815260206004820152603a6024820152600080516020620006e083398151915260448201527f3a20696e76616c6964207369676e6174757265206c656e677468000000000000606482015260840162000187565b620003236200046b565b506020830151604080850151855186939260009185919081106200034b576200034b620006c9565b016020015160f81c9050601b81148015906200036b57508060ff16601c14155b15620003cf5760405162461bcd60e51b815260206004820152603b6024820152600080516020620006e083398151915260448201527f3a20696e76616c6964207369676e617475726520762076616c75650000000000606482015260840162000187565b6040805160008152602081018083528a905260ff83169181019190915260608101849052608081018390526001600160a01b038a169060019060a0016020604051602081039080840390855afa1580156200042e573d6000803e3d6000fd5b505050602060405103516001600160a01b031614955050505050505b9392505050565b60006020825110156200046357600080fd5b508051015190565b60405180606001604052806003906020820280368337509192915050565b6001600160a01b03811681146200049f57600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b60005b83811015620004d5578181015183820152602001620004bb565b50506000910152565b600082601f830112620004f057600080fd5b81516001600160401b03808211156200050d576200050d620004a2565b604051601f8301601f19908116603f01168101908282118183101715620005385762000538620004a2565b816040528381528660208588010111156200055257600080fd5b62000565846020830160208901620004b8565b9695505050505050565b6000806000606084860312156200058557600080fd5b8351620005928162000489565b6020850151604086015191945092506001600160401b03811115620005b657600080fd5b620005c486828701620004de565b9150509250925092565b600080600060608486031215620005e457600080fd5b8351620005f18162000489565b60208501519093506001600160401b03808211156200060f57600080fd5b6200061d87838801620004de565b935060408601519150808211156200063457600080fd5b50620005c486828701620004de565b6000825162000657818460208701620004b8565b9190910192915050565b828152604060208201526000825180604084015262000688816060850160208701620004b8565b601f01601f1916919091016060019392505050565b600060208284031215620006b057600080fd5b81516001600160e01b0319811681146200044a57600080fd5b634e487b7160e01b600052603260045260246000fdfe5369676e617475726556616c696461746f72237265636f7665725369676e6572',
|
|
487
|
-
new AbiCoder().encode(['address', 'bytes32', 'bytes'], [address, arrayify(hash), sig])
|
|
488
|
-
])
|
|
489
|
-
})));
|
|
490
|
-
}
|
|
491
|
-
catch (error) {
|
|
492
|
-
return false;
|
|
493
|
-
}
|
|
494
|
-
}
|
|
495
|
-
// Handle EIP-1271
|
|
496
|
-
if (yield verifyDefault(address, sig, hash, provider))
|
|
497
|
-
return true;
|
|
498
|
-
return yield verifyOldVersion(address, sig, hash, provider);
|
|
499
|
-
});
|
|
500
|
-
}
|
|
501
|
-
function verifyDefault(address, sig, hash, provider) {
|
|
502
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
503
|
-
let returnValue;
|
|
504
|
-
const magicValue = '0x1626ba7e';
|
|
505
|
-
const abi = 'function isValidSignature(bytes32 _hash, bytes memory _signature) public view returns (bytes4 magicValue)';
|
|
506
|
-
try {
|
|
507
|
-
returnValue = yield call(provider, [abi], [address, 'isValidSignature', [arrayify(hash), sig]]);
|
|
508
|
-
}
|
|
509
|
-
catch (e) {
|
|
510
|
-
if (e.message.startsWith('missing revert data in call exception')) {
|
|
511
|
-
return false;
|
|
512
|
-
}
|
|
513
|
-
throw e;
|
|
514
|
-
}
|
|
515
|
-
return isEqual(returnValue, magicValue);
|
|
516
|
-
});
|
|
517
|
-
}
|
|
518
|
-
function verifyOldVersion(address, sig, hash, provider) {
|
|
519
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
520
|
-
const magicValue = '0x20c13b0b';
|
|
521
|
-
const abi = 'function isValidSignature(bytes _hash, bytes memory _signature) public view returns (bytes4 magicValue)';
|
|
522
|
-
const returnValue = yield call(provider, [abi], [address, 'isValidSignature', [arrayify(hash), sig]]);
|
|
523
|
-
return isEqual(returnValue, magicValue);
|
|
524
|
-
});
|
|
525
|
-
}
|
|
526
|
-
|
|
527
|
-
var evm = /*#__PURE__*/Object.freeze({
|
|
528
|
-
__proto__: null,
|
|
529
|
-
getHash: getHash$1,
|
|
530
|
-
'default': verify$1
|
|
531
|
-
});
|
|
532
|
-
|
|
533
|
-
function getHash$2(data, address) {
|
|
534
|
-
const networkType = isStarknetMessage(data) ? starknet : evm;
|
|
535
|
-
return networkType.getHash(data, address);
|
|
536
|
-
}
|
|
537
|
-
function verify$2(address_1, sig_1, data_1) {
|
|
538
|
-
return __awaiter(this, arguments, void 0, function* (address, sig, data, network = '1', options = {}) {
|
|
539
|
-
if (!isStarknetAddress(address) && !isEvmAddress(address)) {
|
|
540
|
-
throw new Error('Invalid address');
|
|
541
|
-
}
|
|
542
|
-
const networkType = isStarknetMessage(data) ? starknet : evm;
|
|
543
|
-
return yield networkType.default(address, sig, data, network, options);
|
|
544
|
-
});
|
|
545
|
-
}
|
|
546
|
-
|
|
547
|
-
var gateways = [
|
|
548
|
-
"ipfs.snapshot.box",
|
|
549
|
-
"snapshot.4everland.link",
|
|
550
|
-
"ipfs.io",
|
|
551
|
-
"ipfs.fleek.co",
|
|
552
|
-
"gateway.pinata.cloud",
|
|
553
|
-
"dweb.link",
|
|
554
|
-
"ipfs.infura.io"
|
|
555
|
-
];
|
|
556
|
-
|
|
557
323
|
var networks = {
|
|
558
324
|
"1": {
|
|
559
325
|
key: "1",
|
|
@@ -2583,18 +2349,298 @@ var networks = {
|
|
|
2583
2349
|
},
|
|
2584
2350
|
start: 7521509,
|
|
2585
2351
|
logo: "ipfs://QmNnGPr1CNvj12SSGzKARtUHv9FyEfE5nES73U4vBWQSJL"
|
|
2352
|
+
},
|
|
2353
|
+
"0x534e5f4d41494e": {
|
|
2354
|
+
key: "sn",
|
|
2355
|
+
name: "Starknet",
|
|
2356
|
+
shortName: "Starknet",
|
|
2357
|
+
chainId: "0x534e5f4d41494e",
|
|
2358
|
+
network: "mainnet",
|
|
2359
|
+
multicall: "0x05754af3760f3356da99aea5c3ec39ccac7783d925a19666ebbeca58ff0087f4",
|
|
2360
|
+
explorer: {
|
|
2361
|
+
url: "https://starkscan.co"
|
|
2362
|
+
},
|
|
2363
|
+
rpc: [
|
|
2364
|
+
],
|
|
2365
|
+
start: 8446,
|
|
2366
|
+
logo: "ipfs://bafkreihbjafyh7eud7r6e5743esaamifcttsvbspfwcrfoc5ykodjdi67m"
|
|
2367
|
+
},
|
|
2368
|
+
"0x534e5f5345504f4c4941": {
|
|
2369
|
+
key: "sn-sep",
|
|
2370
|
+
name: "Starknet Testnet",
|
|
2371
|
+
shortName: "testnet",
|
|
2372
|
+
chainId: "0x534e5f5345504f4c4941",
|
|
2373
|
+
network: "testnet",
|
|
2374
|
+
testnet: true,
|
|
2375
|
+
multicall: "0x05754af3760f3356da99aea5c3ec39ccac7783d925a19666ebbeca58ff0087f4",
|
|
2376
|
+
explorer: {
|
|
2377
|
+
url: "https://sepolia.starkscan.co"
|
|
2378
|
+
},
|
|
2379
|
+
rpc: [
|
|
2380
|
+
],
|
|
2381
|
+
start: 7,
|
|
2382
|
+
logo: "ipfs://bafkreihbjafyh7eud7r6e5743esaamifcttsvbspfwcrfoc5ykodjdi67m"
|
|
2586
2383
|
}
|
|
2587
2384
|
};
|
|
2588
2385
|
|
|
2589
|
-
|
|
2590
|
-
|
|
2591
|
-
|
|
2592
|
-
|
|
2593
|
-
|
|
2594
|
-
|
|
2386
|
+
const DEFAULT_BROVIDER_URL = 'https://rpc.snapshot.org';
|
|
2387
|
+
const DEFAULT_TIMEOUT = 25000;
|
|
2388
|
+
const STARKNET_BROVIDER_KEYS = ['sn', 'sn-sep'];
|
|
2389
|
+
const providerMemo = new Map();
|
|
2390
|
+
const providerFnMap = {
|
|
2391
|
+
evm: getEvmProvider,
|
|
2392
|
+
starknet: getStarknetProvider
|
|
2393
|
+
};
|
|
2394
|
+
function normalizeOptions(options = {}) {
|
|
2395
|
+
var _a;
|
|
2396
|
+
return {
|
|
2397
|
+
broviderUrl: options.broviderUrl || DEFAULT_BROVIDER_URL,
|
|
2398
|
+
timeout: (_a = options.timeout) !== null && _a !== void 0 ? _a : DEFAULT_TIMEOUT
|
|
2399
|
+
};
|
|
2400
|
+
}
|
|
2401
|
+
function getBroviderNetworkId(network) {
|
|
2402
|
+
const config = networks[network];
|
|
2403
|
+
if (!config) {
|
|
2404
|
+
throw new Error(`Network '${network}' is not supported`);
|
|
2595
2405
|
}
|
|
2596
|
-
|
|
2597
|
-
|
|
2406
|
+
return String(config.key);
|
|
2407
|
+
}
|
|
2408
|
+
function getProviderType(networkId) {
|
|
2409
|
+
const isStarknet = STARKNET_BROVIDER_KEYS.includes(networkId);
|
|
2410
|
+
return isStarknet ? 'starknet' : 'evm';
|
|
2411
|
+
}
|
|
2412
|
+
function createMemoKey(networkId, options) {
|
|
2413
|
+
return `${networkId}:${options.broviderUrl}:${options.timeout}`;
|
|
2414
|
+
}
|
|
2415
|
+
// return loose `any` type to avoid typecheck issues on package consumers
|
|
2416
|
+
function getProvider(network, options = {}) {
|
|
2417
|
+
const networkId = getBroviderNetworkId(network);
|
|
2418
|
+
const normalizedOptions = normalizeOptions(options);
|
|
2419
|
+
const memoKey = createMemoKey(networkId, normalizedOptions);
|
|
2420
|
+
const memoized = providerMemo.get(memoKey);
|
|
2421
|
+
if (memoized) {
|
|
2422
|
+
return memoized;
|
|
2423
|
+
}
|
|
2424
|
+
const providerType = getProviderType(networkId);
|
|
2425
|
+
const provider = providerFnMap[providerType](networkId, normalizedOptions);
|
|
2426
|
+
providerMemo.set(memoKey, provider);
|
|
2427
|
+
return provider;
|
|
2428
|
+
}
|
|
2429
|
+
function getEvmProvider(networkId, options) {
|
|
2430
|
+
return new StaticJsonRpcProvider({
|
|
2431
|
+
url: `${options.broviderUrl}/${networkId}`,
|
|
2432
|
+
timeout: options.timeout,
|
|
2433
|
+
allowGzip: true
|
|
2434
|
+
}, Number(networkId));
|
|
2435
|
+
}
|
|
2436
|
+
function getStarknetProvider(networkKey, options) {
|
|
2437
|
+
return new RpcProvider({
|
|
2438
|
+
nodeUrl: `${options.broviderUrl}/${networkKey}`
|
|
2439
|
+
});
|
|
2440
|
+
}
|
|
2441
|
+
|
|
2442
|
+
function signMessage(web3, msg, address) {
|
|
2443
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
2444
|
+
msg = hexlify(new Buffer(msg, 'utf8'));
|
|
2445
|
+
return yield web3.send('personal_sign', [msg, address]);
|
|
2446
|
+
});
|
|
2447
|
+
}
|
|
2448
|
+
function getBlockNumber(provider) {
|
|
2449
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
2450
|
+
try {
|
|
2451
|
+
const blockNumber = yield provider.getBlockNumber();
|
|
2452
|
+
return parseInt(blockNumber);
|
|
2453
|
+
}
|
|
2454
|
+
catch (e) {
|
|
2455
|
+
return Promise.reject();
|
|
2456
|
+
}
|
|
2457
|
+
});
|
|
2458
|
+
}
|
|
2459
|
+
|
|
2460
|
+
const RPC_URLS = {
|
|
2461
|
+
SN_MAIN: 'https://starknet-mainnet.public.blastapi.io',
|
|
2462
|
+
SN_SEPOLIA: 'https://starknet-sepolia.public.blastapi.io'
|
|
2463
|
+
};
|
|
2464
|
+
const ABI = [
|
|
2465
|
+
{
|
|
2466
|
+
name: 'argent::common::account::IAccount',
|
|
2467
|
+
type: 'interface',
|
|
2468
|
+
items: [
|
|
2469
|
+
{
|
|
2470
|
+
name: 'is_valid_signature',
|
|
2471
|
+
type: 'function',
|
|
2472
|
+
inputs: [
|
|
2473
|
+
{
|
|
2474
|
+
name: 'hash',
|
|
2475
|
+
type: 'core::felt252'
|
|
2476
|
+
},
|
|
2477
|
+
{
|
|
2478
|
+
name: 'signature',
|
|
2479
|
+
type: 'core::array::Array::<core::felt252>'
|
|
2480
|
+
}
|
|
2481
|
+
],
|
|
2482
|
+
outputs: [
|
|
2483
|
+
{
|
|
2484
|
+
type: 'core::felt252'
|
|
2485
|
+
}
|
|
2486
|
+
],
|
|
2487
|
+
state_mutability: 'view'
|
|
2488
|
+
}
|
|
2489
|
+
]
|
|
2490
|
+
}
|
|
2491
|
+
];
|
|
2492
|
+
function getProvider$1(network, options) {
|
|
2493
|
+
var _a;
|
|
2494
|
+
if (!RPC_URLS[network])
|
|
2495
|
+
throw new Error('Invalid network');
|
|
2496
|
+
return new RpcProvider({
|
|
2497
|
+
nodeUrl: (_a = options === null || options === void 0 ? void 0 : options.broviderUrl) !== null && _a !== void 0 ? _a : RPC_URLS[network]
|
|
2498
|
+
});
|
|
2499
|
+
}
|
|
2500
|
+
function isStarknetMessage(data) {
|
|
2501
|
+
return !!data.primaryType && !!data.types.StarkNetDomain;
|
|
2502
|
+
}
|
|
2503
|
+
function getHash(data, address) {
|
|
2504
|
+
const { domain, types, primaryType, message } = data;
|
|
2505
|
+
return typedData.getMessageHash({ types, primaryType, domain, message }, address);
|
|
2506
|
+
}
|
|
2507
|
+
function verify(address_1, sig_1, data_1) {
|
|
2508
|
+
return __awaiter(this, arguments, void 0, function* (address, sig, data, network = 'SN_MAIN', options = {}) {
|
|
2509
|
+
try {
|
|
2510
|
+
const contractAccount = new Contract(ABI, address, getProvider$1(network, options));
|
|
2511
|
+
if (sig.length < 2) {
|
|
2512
|
+
throw new Error('Invalid signature format');
|
|
2513
|
+
}
|
|
2514
|
+
const result = yield contractAccount.is_valid_signature(getHash(data, address), sig.slice(-2));
|
|
2515
|
+
return BigNumber.from(result).eq(BigNumber.from('370462705988'));
|
|
2516
|
+
}
|
|
2517
|
+
catch (e) {
|
|
2518
|
+
if (e.message.includes('Contract not found')) {
|
|
2519
|
+
throw new Error('Contract not deployed');
|
|
2520
|
+
}
|
|
2521
|
+
throw e;
|
|
2522
|
+
}
|
|
2523
|
+
});
|
|
2524
|
+
}
|
|
2525
|
+
|
|
2526
|
+
var starknet = /*#__PURE__*/Object.freeze({
|
|
2527
|
+
__proto__: null,
|
|
2528
|
+
isStarknetMessage: isStarknetMessage,
|
|
2529
|
+
getHash: getHash,
|
|
2530
|
+
'default': verify
|
|
2531
|
+
});
|
|
2532
|
+
|
|
2533
|
+
const ERC6492_DETECTION_SUFFIX = '6492649264926492649264926492649264926492649264926492649264926492';
|
|
2534
|
+
function isEqual(a, b) {
|
|
2535
|
+
return a.toLowerCase() === b.toLowerCase();
|
|
2536
|
+
}
|
|
2537
|
+
function getHash$1(data) {
|
|
2538
|
+
const { domain, types, message } = data;
|
|
2539
|
+
return _TypedDataEncoder.hash(domain, types, message);
|
|
2540
|
+
}
|
|
2541
|
+
function verify$1(address_1, sig_1, data_1) {
|
|
2542
|
+
return __awaiter(this, arguments, void 0, function* (address, sig, data, network = '1', options = {}) {
|
|
2543
|
+
const { domain, types, message } = data;
|
|
2544
|
+
try {
|
|
2545
|
+
const recoverAddress = verifyTypedData(domain, types, message, sig);
|
|
2546
|
+
if (isEqual(address, recoverAddress))
|
|
2547
|
+
return true;
|
|
2548
|
+
}
|
|
2549
|
+
catch (e) { }
|
|
2550
|
+
const provider = getProvider(network, options);
|
|
2551
|
+
const hash = getHash$1(data);
|
|
2552
|
+
// Handle EIP-6492
|
|
2553
|
+
// https://eips.ethereum.org/EIPS/eip-6492
|
|
2554
|
+
//
|
|
2555
|
+
// We can actually replace verifyTypedData and verifyDefault with the following code,
|
|
2556
|
+
// but https://github.com/AmbireTech/signature-validator/blob/main/contracts/DeploylessUniversalSigValidator.sol
|
|
2557
|
+
// also can send an extra network request to the provider. (with verifyTypedData we don't send any extra request)
|
|
2558
|
+
//
|
|
2559
|
+
if (sig.endsWith(ERC6492_DETECTION_SUFFIX)) {
|
|
2560
|
+
try {
|
|
2561
|
+
return ('0x01' ===
|
|
2562
|
+
(yield provider.call({
|
|
2563
|
+
data: concat([
|
|
2564
|
+
'0x60806040523480156200001157600080fd5b50604051620007003803806200070083398101604081905262000034916200056f565b6000620000438484846200004f565b9050806000526001601ff35b600080846001600160a01b0316803b806020016040519081016040528181526000908060200190933c90507f6492649264926492649264926492649264926492649264926492649264926492620000a68462000451565b036200021f57600060608085806020019051810190620000c79190620005ce565b8651929550909350915060000362000192576000836001600160a01b031683604051620000f5919062000643565b6000604051808303816000865af19150503d806000811462000134576040519150601f19603f3d011682016040523d82523d6000602084013e62000139565b606091505b5050905080620001905760405162461bcd60e51b815260206004820152601e60248201527f5369676e617475726556616c696461746f723a206465706c6f796d656e74000060448201526064015b60405180910390fd5b505b604051630b135d3f60e11b808252906001600160a01b038a1690631626ba7e90620001c4908b90869060040162000661565b602060405180830381865afa158015620001e2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200020891906200069d565b6001600160e01b031916149450505050506200044a565b805115620002b157604051630b135d3f60e11b808252906001600160a01b03871690631626ba7e9062000259908890889060040162000661565b602060405180830381865afa15801562000277573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200029d91906200069d565b6001600160e01b031916149150506200044a565b8251604114620003195760405162461bcd60e51b815260206004820152603a6024820152600080516020620006e083398151915260448201527f3a20696e76616c6964207369676e6174757265206c656e677468000000000000606482015260840162000187565b620003236200046b565b506020830151604080850151855186939260009185919081106200034b576200034b620006c9565b016020015160f81c9050601b81148015906200036b57508060ff16601c14155b15620003cf5760405162461bcd60e51b815260206004820152603b6024820152600080516020620006e083398151915260448201527f3a20696e76616c6964207369676e617475726520762076616c75650000000000606482015260840162000187565b6040805160008152602081018083528a905260ff83169181019190915260608101849052608081018390526001600160a01b038a169060019060a0016020604051602081039080840390855afa1580156200042e573d6000803e3d6000fd5b505050602060405103516001600160a01b031614955050505050505b9392505050565b60006020825110156200046357600080fd5b508051015190565b60405180606001604052806003906020820280368337509192915050565b6001600160a01b03811681146200049f57600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b60005b83811015620004d5578181015183820152602001620004bb565b50506000910152565b600082601f830112620004f057600080fd5b81516001600160401b03808211156200050d576200050d620004a2565b604051601f8301601f19908116603f01168101908282118183101715620005385762000538620004a2565b816040528381528660208588010111156200055257600080fd5b62000565846020830160208901620004b8565b9695505050505050565b6000806000606084860312156200058557600080fd5b8351620005928162000489565b6020850151604086015191945092506001600160401b03811115620005b657600080fd5b620005c486828701620004de565b9150509250925092565b600080600060608486031215620005e457600080fd5b8351620005f18162000489565b60208501519093506001600160401b03808211156200060f57600080fd5b6200061d87838801620004de565b935060408601519150808211156200063457600080fd5b50620005c486828701620004de565b6000825162000657818460208701620004b8565b9190910192915050565b828152604060208201526000825180604084015262000688816060850160208701620004b8565b601f01601f1916919091016060019392505050565b600060208284031215620006b057600080fd5b81516001600160e01b0319811681146200044a57600080fd5b634e487b7160e01b600052603260045260246000fdfe5369676e617475726556616c696461746f72237265636f7665725369676e6572',
|
|
2565
|
+
new AbiCoder().encode(['address', 'bytes32', 'bytes'], [address, arrayify(hash), sig])
|
|
2566
|
+
])
|
|
2567
|
+
})));
|
|
2568
|
+
}
|
|
2569
|
+
catch (error) {
|
|
2570
|
+
return false;
|
|
2571
|
+
}
|
|
2572
|
+
}
|
|
2573
|
+
// Handle EIP-1271
|
|
2574
|
+
if (yield verifyDefault(address, sig, hash, provider))
|
|
2575
|
+
return true;
|
|
2576
|
+
return yield verifyOldVersion(address, sig, hash, provider);
|
|
2577
|
+
});
|
|
2578
|
+
}
|
|
2579
|
+
function verifyDefault(address, sig, hash, provider) {
|
|
2580
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
2581
|
+
let returnValue;
|
|
2582
|
+
const magicValue = '0x1626ba7e';
|
|
2583
|
+
const abi = 'function isValidSignature(bytes32 _hash, bytes memory _signature) public view returns (bytes4 magicValue)';
|
|
2584
|
+
try {
|
|
2585
|
+
returnValue = yield call(provider, [abi], [address, 'isValidSignature', [arrayify(hash), sig]]);
|
|
2586
|
+
}
|
|
2587
|
+
catch (e) {
|
|
2588
|
+
if (e.message.startsWith('missing revert data in call exception')) {
|
|
2589
|
+
return false;
|
|
2590
|
+
}
|
|
2591
|
+
throw e;
|
|
2592
|
+
}
|
|
2593
|
+
return isEqual(returnValue, magicValue);
|
|
2594
|
+
});
|
|
2595
|
+
}
|
|
2596
|
+
function verifyOldVersion(address, sig, hash, provider) {
|
|
2597
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
2598
|
+
const magicValue = '0x20c13b0b';
|
|
2599
|
+
const abi = 'function isValidSignature(bytes _hash, bytes memory _signature) public view returns (bytes4 magicValue)';
|
|
2600
|
+
const returnValue = yield call(provider, [abi], [address, 'isValidSignature', [arrayify(hash), sig]]);
|
|
2601
|
+
return isEqual(returnValue, magicValue);
|
|
2602
|
+
});
|
|
2603
|
+
}
|
|
2604
|
+
|
|
2605
|
+
var evm = /*#__PURE__*/Object.freeze({
|
|
2606
|
+
__proto__: null,
|
|
2607
|
+
getHash: getHash$1,
|
|
2608
|
+
'default': verify$1
|
|
2609
|
+
});
|
|
2610
|
+
|
|
2611
|
+
function getHash$2(data, address) {
|
|
2612
|
+
const networkType = isStarknetMessage(data) ? starknet : evm;
|
|
2613
|
+
return networkType.getHash(data, address);
|
|
2614
|
+
}
|
|
2615
|
+
function verify$2(address_1, sig_1, data_1) {
|
|
2616
|
+
return __awaiter(this, arguments, void 0, function* (address, sig, data, network = '1', options = {}) {
|
|
2617
|
+
if (!isStarknetAddress(address) && !isEvmAddress(address)) {
|
|
2618
|
+
throw new Error('Invalid address');
|
|
2619
|
+
}
|
|
2620
|
+
const networkType = isStarknetMessage(data) ? starknet : evm;
|
|
2621
|
+
return yield networkType.default(address, sig, data, network, options);
|
|
2622
|
+
});
|
|
2623
|
+
}
|
|
2624
|
+
|
|
2625
|
+
var gateways = [
|
|
2626
|
+
"ipfs.snapshot.box",
|
|
2627
|
+
"snapshot.4everland.link",
|
|
2628
|
+
"ipfs.io",
|
|
2629
|
+
"ipfs.fleek.co",
|
|
2630
|
+
"gateway.pinata.cloud",
|
|
2631
|
+
"dweb.link",
|
|
2632
|
+
"ipfs.infura.io"
|
|
2633
|
+
];
|
|
2634
|
+
|
|
2635
|
+
class SingleChoiceVoting {
|
|
2636
|
+
constructor(proposal, votes, strategies, selected) {
|
|
2637
|
+
this.proposal = proposal;
|
|
2638
|
+
this.votes = votes;
|
|
2639
|
+
this.strategies = strategies;
|
|
2640
|
+
this.selected = selected;
|
|
2641
|
+
}
|
|
2642
|
+
static isValidChoice(voteChoice, proposalChoices) {
|
|
2643
|
+
return (typeof voteChoice === 'number' &&
|
|
2598
2644
|
(proposalChoices === null || proposalChoices === void 0 ? void 0 : proposalChoices[voteChoice - 1]) !== undefined);
|
|
2599
2645
|
}
|
|
2600
2646
|
getValidVotes() {
|
|
@@ -3183,6 +3229,209 @@ function fetchData(_a) {
|
|
|
3183
3229
|
});
|
|
3184
3230
|
}
|
|
3185
3231
|
|
|
3232
|
+
const multicallAbi = [
|
|
3233
|
+
'function aggregate(tuple(address target, bytes callData)[] calls) view returns (uint256 blockNumber, bytes[] returnData)'
|
|
3234
|
+
];
|
|
3235
|
+
function multicall(address_1, provider_1, abi_1, calls_1, limit_1) {
|
|
3236
|
+
return __awaiter(this, arguments, void 0, function* (address, provider, abi, calls, limit, options = {}) {
|
|
3237
|
+
const multi = new Contract$1(address, multicallAbi, provider);
|
|
3238
|
+
const itf = new Interface(abi);
|
|
3239
|
+
try {
|
|
3240
|
+
const pages = Math.ceil(calls.length / limit);
|
|
3241
|
+
const promises = [];
|
|
3242
|
+
Array.from(Array(pages)).forEach((x, i) => {
|
|
3243
|
+
const callsInPage = calls.slice(limit * i, limit * (i + 1));
|
|
3244
|
+
promises.push(multi.aggregate(callsInPage.map((call) => [
|
|
3245
|
+
call[0].toLowerCase(),
|
|
3246
|
+
itf.encodeFunctionData(call[1], call[2])
|
|
3247
|
+
]), options));
|
|
3248
|
+
});
|
|
3249
|
+
let results = yield Promise.all(promises);
|
|
3250
|
+
results = results.reduce((prev, [, res]) => prev.concat(res), []);
|
|
3251
|
+
return results.map((call, i) => itf.decodeFunctionResult(calls[i][1], call));
|
|
3252
|
+
}
|
|
3253
|
+
catch (e) {
|
|
3254
|
+
return Promise.reject(e);
|
|
3255
|
+
}
|
|
3256
|
+
});
|
|
3257
|
+
}
|
|
3258
|
+
|
|
3259
|
+
/**
|
|
3260
|
+
* Parses the raw result from a Starknet function call based on its ABI.
|
|
3261
|
+
* It handles different types like felt252, u8, u256, etc., and decodes them accordingly.
|
|
3262
|
+
* @param rawResult - The raw result from the Starknet function call.
|
|
3263
|
+
* @param functionAbi - The ABI of the function that was called.
|
|
3264
|
+
* @returns The parsed result in a more usable format.
|
|
3265
|
+
*/
|
|
3266
|
+
function parseStarknetResult(rawResult, functionAbi) {
|
|
3267
|
+
if (!functionAbi ||
|
|
3268
|
+
!functionAbi.outputs ||
|
|
3269
|
+
!Array.isArray(rawResult) ||
|
|
3270
|
+
rawResult.length === 0) {
|
|
3271
|
+
return rawResult;
|
|
3272
|
+
}
|
|
3273
|
+
const output = functionAbi.outputs[0];
|
|
3274
|
+
const rawValue = rawResult[0];
|
|
3275
|
+
try {
|
|
3276
|
+
switch (output.type) {
|
|
3277
|
+
case 'core::felt252':
|
|
3278
|
+
// Try to decode as shortString (for name, symbol)
|
|
3279
|
+
try {
|
|
3280
|
+
return shortString.decodeShortString(rawValue);
|
|
3281
|
+
}
|
|
3282
|
+
catch (_a) {
|
|
3283
|
+
// If shortString decode fails, return as hex
|
|
3284
|
+
return rawValue;
|
|
3285
|
+
}
|
|
3286
|
+
// Unsigned integers
|
|
3287
|
+
case 'core::integer::u8':
|
|
3288
|
+
case 'core::integer::u16':
|
|
3289
|
+
case 'core::integer::u32':
|
|
3290
|
+
case 'core::integer::u64':
|
|
3291
|
+
return parseInt(rawValue, 16);
|
|
3292
|
+
case 'core::integer::u128':
|
|
3293
|
+
case 'core::integer::usize':
|
|
3294
|
+
return BigInt(rawValue).toString();
|
|
3295
|
+
case 'core::integer::u256':
|
|
3296
|
+
return uint256.uint256ToBN({
|
|
3297
|
+
low: rawValue,
|
|
3298
|
+
high: rawResult[1] || '0x0'
|
|
3299
|
+
});
|
|
3300
|
+
// Signed integers
|
|
3301
|
+
case 'core::integer::i8':
|
|
3302
|
+
case 'core::integer::i16':
|
|
3303
|
+
case 'core::integer::i32':
|
|
3304
|
+
case 'core::integer::i64':
|
|
3305
|
+
return parseInt(rawValue, 16);
|
|
3306
|
+
case 'core::integer::i128':
|
|
3307
|
+
return BigInt(rawValue).toString();
|
|
3308
|
+
// Boolean type
|
|
3309
|
+
case 'core::bool':
|
|
3310
|
+
return rawValue === '0x1' || rawValue === '0x01';
|
|
3311
|
+
// Address types
|
|
3312
|
+
case 'core::starknet::contract_address::ContractAddress':
|
|
3313
|
+
case 'core::starknet::class_hash::ClassHash':
|
|
3314
|
+
case 'core::starknet::storage_access::StorageAddress':
|
|
3315
|
+
return rawValue;
|
|
3316
|
+
// Byte array
|
|
3317
|
+
case 'core::bytes_31::bytes31':
|
|
3318
|
+
return rawValue;
|
|
3319
|
+
default:
|
|
3320
|
+
// Return raw value for unknown types
|
|
3321
|
+
return rawValue;
|
|
3322
|
+
}
|
|
3323
|
+
}
|
|
3324
|
+
catch (_b) {
|
|
3325
|
+
// Fallback to raw result if parsing fails
|
|
3326
|
+
return rawResult;
|
|
3327
|
+
}
|
|
3328
|
+
}
|
|
3329
|
+
/**
|
|
3330
|
+
* Partitions the responses from a Starknet multicall into individual call results.
|
|
3331
|
+
* Each response starts with its length, followed by the actual response data.
|
|
3332
|
+
* @param responses - The array of responses from the Starknet multicall.
|
|
3333
|
+
* @returns An array of arrays, where each inner array contains the response data for a single call.
|
|
3334
|
+
*/
|
|
3335
|
+
const partitionResponses = (responses) => {
|
|
3336
|
+
if (responses.length === 0) {
|
|
3337
|
+
return [];
|
|
3338
|
+
}
|
|
3339
|
+
const [responseLength, ...restResponses] = responses;
|
|
3340
|
+
const responseLengthInt = Number(num.toBigInt(responseLength));
|
|
3341
|
+
const response = restResponses.slice(0, responseLengthInt);
|
|
3342
|
+
const remainingResponses = restResponses.slice(responseLengthInt);
|
|
3343
|
+
return [response, ...partitionResponses(remainingResponses)];
|
|
3344
|
+
};
|
|
3345
|
+
function multicall$1(address_1, provider_1, abi_1, calls_1, limit_1) {
|
|
3346
|
+
return __awaiter(this, arguments, void 0, function* (address, provider, abi, calls, limit, options = {}) {
|
|
3347
|
+
const callData = calls.map((call) => {
|
|
3348
|
+
return {
|
|
3349
|
+
contractAddress: call[0],
|
|
3350
|
+
entrypoint: call[1],
|
|
3351
|
+
calldata: call[2] || []
|
|
3352
|
+
};
|
|
3353
|
+
});
|
|
3354
|
+
// Chunk calls into batches based on limit
|
|
3355
|
+
const chunks = [];
|
|
3356
|
+
for (let i = 0; i < callData.length; i += limit) {
|
|
3357
|
+
chunks.push(callData.slice(i, i + limit));
|
|
3358
|
+
}
|
|
3359
|
+
// Process each chunk
|
|
3360
|
+
const paginatedResults = yield Promise.all(chunks.map((chunk) => {
|
|
3361
|
+
var _a;
|
|
3362
|
+
return provider.callContract({
|
|
3363
|
+
contractAddress: address,
|
|
3364
|
+
entrypoint: 'aggregate',
|
|
3365
|
+
calldata: transaction.fromCallsToExecuteCalldata(chunk)
|
|
3366
|
+
}, (_a = options.blockTag) !== null && _a !== void 0 ? _a : 'latest');
|
|
3367
|
+
}));
|
|
3368
|
+
const callResults = paginatedResults
|
|
3369
|
+
.map((callContractResult) => {
|
|
3370
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
3371
|
+
const [_blockNumber, _totalLength, ...results] = callContractResult;
|
|
3372
|
+
return partitionResponses(results);
|
|
3373
|
+
})
|
|
3374
|
+
.flat();
|
|
3375
|
+
return callResults.map((result, index) => {
|
|
3376
|
+
const [, functionName] = calls[index];
|
|
3377
|
+
const functionAbi = abi.find((item) => item.name === functionName);
|
|
3378
|
+
return [parseStarknetResult(result, functionAbi)];
|
|
3379
|
+
});
|
|
3380
|
+
});
|
|
3381
|
+
}
|
|
3382
|
+
|
|
3383
|
+
class Multicaller {
|
|
3384
|
+
constructor(network, provider, abi, options = {}) {
|
|
3385
|
+
this.options = {};
|
|
3386
|
+
this.calls = [];
|
|
3387
|
+
this.paths = [];
|
|
3388
|
+
this.network = network;
|
|
3389
|
+
this.provider = provider;
|
|
3390
|
+
this.abi = abi;
|
|
3391
|
+
this.options = options;
|
|
3392
|
+
}
|
|
3393
|
+
call(path, address, fn, params) {
|
|
3394
|
+
this.calls.push([address, fn, params]);
|
|
3395
|
+
this.paths.push(path);
|
|
3396
|
+
return this;
|
|
3397
|
+
}
|
|
3398
|
+
execute(from) {
|
|
3399
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
3400
|
+
const obj = from || {};
|
|
3401
|
+
const result = yield multicall$2(this.network, this.provider, this.abi, this.calls, this.options);
|
|
3402
|
+
result.forEach((r, i) => set(obj, this.paths[i], r.length > 1 ? r : r[0]));
|
|
3403
|
+
this.calls = [];
|
|
3404
|
+
this.paths = [];
|
|
3405
|
+
return obj;
|
|
3406
|
+
});
|
|
3407
|
+
}
|
|
3408
|
+
}
|
|
3409
|
+
|
|
3410
|
+
const STARKNET_CHAIN_IDS = [
|
|
3411
|
+
constants$1.StarknetChainId.SN_MAIN,
|
|
3412
|
+
constants$1.StarknetChainId.SN_SEPOLIA
|
|
3413
|
+
];
|
|
3414
|
+
const MULTICALLS_FN = {
|
|
3415
|
+
evm: multicall,
|
|
3416
|
+
starknet: multicall$1
|
|
3417
|
+
};
|
|
3418
|
+
function multicall$2(network_1, provider_1, abi_1, calls_1) {
|
|
3419
|
+
return __awaiter(this, arguments, void 0, function* (network, provider, abi, calls, options = {}) {
|
|
3420
|
+
const address = (options === null || options === void 0 ? void 0 : options.multicallAddress) || networks[network].multicall;
|
|
3421
|
+
if (!address) {
|
|
3422
|
+
throw new Error('missing multicall address');
|
|
3423
|
+
}
|
|
3424
|
+
const multicallOptions = Object.assign({}, options);
|
|
3425
|
+
const limit = (multicallOptions === null || multicallOptions === void 0 ? void 0 : multicallOptions.limit) || 500;
|
|
3426
|
+
delete multicallOptions.limit;
|
|
3427
|
+
delete multicallOptions.multicallAddress;
|
|
3428
|
+
const protocol = STARKNET_CHAIN_IDS.includes(network)
|
|
3429
|
+
? 'starknet'
|
|
3430
|
+
: 'evm';
|
|
3431
|
+
return MULTICALLS_FN[protocol](address, provider, abi, calls, limit, multicallOptions);
|
|
3432
|
+
});
|
|
3433
|
+
}
|
|
3434
|
+
|
|
3186
3435
|
const MUTED_ERRORS = [
|
|
3187
3436
|
// mute error from coinbase, when the subdomain is not found
|
|
3188
3437
|
// most other resolvers just return an empty address
|
|
@@ -3196,16 +3445,6 @@ const ENS_ABI = [
|
|
|
3196
3445
|
'function resolver(bytes32 node) view returns (address)' // ENS registry ABI
|
|
3197
3446
|
];
|
|
3198
3447
|
const EMPTY_ADDRESS = '0x0000000000000000000000000000000000000000';
|
|
3199
|
-
const STARKNET_NETWORKS = {
|
|
3200
|
-
'0x534e5f4d41494e': {
|
|
3201
|
-
name: 'Starknet',
|
|
3202
|
-
testnet: false
|
|
3203
|
-
},
|
|
3204
|
-
'0x534e5f5345504f4c4941': {
|
|
3205
|
-
name: 'Starknet Sepolia',
|
|
3206
|
-
testnet: true
|
|
3207
|
-
}
|
|
3208
|
-
};
|
|
3209
3448
|
const scoreApiHeaders = {
|
|
3210
3449
|
Accept: 'application/json',
|
|
3211
3450
|
'Content-Type': 'application/json'
|
|
@@ -3329,22 +3568,6 @@ ajv.addKeyword({
|
|
|
3329
3568
|
message: 'network not allowed'
|
|
3330
3569
|
}
|
|
3331
3570
|
});
|
|
3332
|
-
ajv.addKeyword({
|
|
3333
|
-
keyword: 'starknetNetwork',
|
|
3334
|
-
validate: function (schema, data) {
|
|
3335
|
-
// @ts-ignore
|
|
3336
|
-
const snapshotEnv = this.snapshotEnv || 'default';
|
|
3337
|
-
if (snapshotEnv === 'mainnet') {
|
|
3338
|
-
return Object.keys(STARKNET_NETWORKS)
|
|
3339
|
-
.filter((id) => !STARKNET_NETWORKS[id].testnet)
|
|
3340
|
-
.includes(data);
|
|
3341
|
-
}
|
|
3342
|
-
return Object.keys(STARKNET_NETWORKS).includes(data);
|
|
3343
|
-
},
|
|
3344
|
-
error: {
|
|
3345
|
-
message: 'network not allowed'
|
|
3346
|
-
}
|
|
3347
|
-
});
|
|
3348
3571
|
// Custom URL format to allow empty string values
|
|
3349
3572
|
// https://github.com/snapshot-labs/snapshot.js/pull/541/files
|
|
3350
3573
|
ajv.addFormat('customUrl', {
|
|
@@ -3413,36 +3636,6 @@ function call(provider, abi, call, options) {
|
|
|
3413
3636
|
}
|
|
3414
3637
|
});
|
|
3415
3638
|
}
|
|
3416
|
-
function multicall(network, provider, abi, calls, options) {
|
|
3417
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
3418
|
-
const multicallAbi = [
|
|
3419
|
-
'function aggregate(tuple(address target, bytes callData)[] calls) view returns (uint256 blockNumber, bytes[] returnData)'
|
|
3420
|
-
];
|
|
3421
|
-
const multicallAddress = (options === null || options === void 0 ? void 0 : options.multicallAddress) || networks[network].multicall;
|
|
3422
|
-
const multi = new Contract$1(multicallAddress, multicallAbi, provider);
|
|
3423
|
-
const itf = new Interface(abi);
|
|
3424
|
-
try {
|
|
3425
|
-
const max = (options === null || options === void 0 ? void 0 : options.limit) || 500;
|
|
3426
|
-
if (options === null || options === void 0 ? void 0 : options.limit)
|
|
3427
|
-
delete options.limit;
|
|
3428
|
-
const pages = Math.ceil(calls.length / max);
|
|
3429
|
-
const promises = [];
|
|
3430
|
-
Array.from(Array(pages)).forEach((x, i) => {
|
|
3431
|
-
const callsInPage = calls.slice(max * i, max * (i + 1));
|
|
3432
|
-
promises.push(multi.aggregate(callsInPage.map((call) => [
|
|
3433
|
-
call[0].toLowerCase(),
|
|
3434
|
-
itf.encodeFunctionData(call[1], call[2])
|
|
3435
|
-
]), options || {}));
|
|
3436
|
-
});
|
|
3437
|
-
let results = yield Promise.all(promises);
|
|
3438
|
-
results = results.reduce((prev, [, res]) => prev.concat(res), []);
|
|
3439
|
-
return results.map((call, i) => itf.decodeFunctionResult(calls[i][1], call));
|
|
3440
|
-
}
|
|
3441
|
-
catch (e) {
|
|
3442
|
-
return Promise.reject(e);
|
|
3443
|
-
}
|
|
3444
|
-
});
|
|
3445
|
-
}
|
|
3446
3639
|
function subgraphRequest(url_1, query_1) {
|
|
3447
3640
|
return __awaiter(this, arguments, void 0, function* (url, query, options = {}) {
|
|
3448
3641
|
const body = { query: jsonToGraphQLQuery({ query }) };
|
|
@@ -3674,7 +3867,7 @@ function getEnsTextRecord(ens_1, record_1) {
|
|
|
3674
3867
|
[ensHash, record]
|
|
3675
3868
|
]) // Query for text record from each resolver
|
|
3676
3869
|
];
|
|
3677
|
-
const [[resolverAddress], ...textRecords] = yield multicall(network, provider, ENS_ABI, calls, multicallOptions);
|
|
3870
|
+
const [[resolverAddress], ...textRecords] = (yield multicall$2(network, provider, ENS_ABI, calls, multicallOptions));
|
|
3678
3871
|
const resolverIndex = ensResolvers.indexOf(resolverAddress);
|
|
3679
3872
|
return resolverIndex !== -1 ? (_b = textRecords[resolverIndex]) === null || _b === void 0 ? void 0 : _b[0] : null;
|
|
3680
3873
|
});
|
|
@@ -3837,7 +4030,7 @@ function inputError(message) {
|
|
|
3837
4030
|
}
|
|
3838
4031
|
var utils = {
|
|
3839
4032
|
call,
|
|
3840
|
-
multicall,
|
|
4033
|
+
multicall: multicall$2,
|
|
3841
4034
|
subgraphRequest,
|
|
3842
4035
|
ipfsGet,
|
|
3843
4036
|
getUrl,
|
|
@@ -4127,8 +4320,7 @@ var definitions = {
|
|
|
4127
4320
|
type: "string",
|
|
4128
4321
|
snapshotNetwork: true,
|
|
4129
4322
|
title: "network",
|
|
4130
|
-
minLength: 1
|
|
4131
|
-
maxLength: 32
|
|
4323
|
+
minLength: 1
|
|
4132
4324
|
},
|
|
4133
4325
|
symbol: {
|
|
4134
4326
|
type: "string",
|
|
@@ -4171,7 +4363,6 @@ var definitions = {
|
|
|
4171
4363
|
},
|
|
4172
4364
|
network: {
|
|
4173
4365
|
type: "string",
|
|
4174
|
-
maxLength: 12,
|
|
4175
4366
|
title: "network",
|
|
4176
4367
|
snapshotNetwork: true
|
|
4177
4368
|
},
|
|
@@ -4370,15 +4561,7 @@ var definitions = {
|
|
|
4370
4561
|
type: "string",
|
|
4371
4562
|
title: "Delegation network",
|
|
4372
4563
|
description: "The network of your delegation contract",
|
|
4373
|
-
|
|
4374
|
-
{
|
|
4375
|
-
snapshotNetwork: true
|
|
4376
|
-
},
|
|
4377
|
-
{
|
|
4378
|
-
starknetNetwork: true
|
|
4379
|
-
}
|
|
4380
|
-
],
|
|
4381
|
-
errorMessage: "Must be a valid network"
|
|
4564
|
+
snapshotNetwork: true
|
|
4382
4565
|
},
|
|
4383
4566
|
delegationApi: {
|
|
4384
4567
|
type: "string",
|
|
@@ -4520,15 +4703,7 @@ var definitions = {
|
|
|
4520
4703
|
network: {
|
|
4521
4704
|
type: "string",
|
|
4522
4705
|
title: "Network",
|
|
4523
|
-
|
|
4524
|
-
{
|
|
4525
|
-
snapshotNetwork: true
|
|
4526
|
-
},
|
|
4527
|
-
{
|
|
4528
|
-
starknetNetwork: true
|
|
4529
|
-
}
|
|
4530
|
-
],
|
|
4531
|
-
errorMessage: "Must be a valid network"
|
|
4706
|
+
snapshotNetwork: true
|
|
4532
4707
|
}
|
|
4533
4708
|
},
|
|
4534
4709
|
required: [
|