@snapshot-labs/snapshot.js 0.13.0 → 0.14.0
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 +505 -329
- package/dist/snapshot.esm.js +506 -330
- 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/utils/provider.ts +91 -44
- package/src/utils.spec.js +247 -46
- package/src/utils.ts +9 -78
- package/dist/src/utils/multicaller.d.ts +0 -12
package/dist/snapshot.cjs.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var fetch = require('cross-fetch');
|
|
4
|
-
var abi = require('@ethersproject/abi');
|
|
5
4
|
var contracts = require('@ethersproject/contracts');
|
|
6
5
|
var address = require('@ethersproject/address');
|
|
7
6
|
var units = require('@ethersproject/units');
|
|
@@ -10,12 +9,13 @@ var jsonToGraphqlQuery = require('json-to-graphql-query');
|
|
|
10
9
|
var Ajv = require('ajv');
|
|
11
10
|
var addFormats = require('ajv-formats');
|
|
12
11
|
var addErrors = require('ajv-errors');
|
|
13
|
-
var
|
|
14
|
-
var providers$1 = require('@ethersproject/providers');
|
|
15
|
-
var bytes = require('@ethersproject/bytes');
|
|
12
|
+
var providers = require('@ethersproject/providers');
|
|
16
13
|
var starknet$1 = require('starknet');
|
|
14
|
+
var bytes = require('@ethersproject/bytes');
|
|
17
15
|
var bignumber = require('@ethersproject/bignumber');
|
|
18
16
|
var wallet = require('@ethersproject/wallet');
|
|
17
|
+
var abi = require('@ethersproject/abi');
|
|
18
|
+
var set = require('lodash.set');
|
|
19
19
|
|
|
20
20
|
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
21
21
|
|
|
@@ -283,33 +283,6 @@ var constants = {
|
|
|
283
283
|
local: local
|
|
284
284
|
};
|
|
285
285
|
|
|
286
|
-
class Multicaller {
|
|
287
|
-
constructor(network, provider, abi, options) {
|
|
288
|
-
this.options = {};
|
|
289
|
-
this.calls = [];
|
|
290
|
-
this.paths = [];
|
|
291
|
-
this.network = network;
|
|
292
|
-
this.provider = provider;
|
|
293
|
-
this.abi = abi;
|
|
294
|
-
this.options = options || {};
|
|
295
|
-
}
|
|
296
|
-
call(path, address, fn, params) {
|
|
297
|
-
this.calls.push([address, fn, params]);
|
|
298
|
-
this.paths.push(path);
|
|
299
|
-
return this;
|
|
300
|
-
}
|
|
301
|
-
execute(from) {
|
|
302
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
303
|
-
const obj = from || {};
|
|
304
|
-
const result = yield multicall(this.network, this.provider, this.abi, this.calls, this.options);
|
|
305
|
-
result.forEach((r, i) => set__default['default'](obj, this.paths[i], r.length > 1 ? r : r[0]));
|
|
306
|
-
this.calls = [];
|
|
307
|
-
this.paths = [];
|
|
308
|
-
return obj;
|
|
309
|
-
});
|
|
310
|
-
}
|
|
311
|
-
}
|
|
312
|
-
|
|
313
286
|
let cache = {};
|
|
314
287
|
let expirationTime = 0;
|
|
315
288
|
function getSnapshots(network_1, snapshot_1, provider_1, networks_1) {
|
|
@@ -357,213 +330,6 @@ function getSnapshots(network_1, snapshot_1, provider_1, networks_1) {
|
|
|
357
330
|
});
|
|
358
331
|
}
|
|
359
332
|
|
|
360
|
-
const providers = {};
|
|
361
|
-
const DEFAULT_BROVIDER_URL = 'https://rpc.snapshot.org';
|
|
362
|
-
const DEFAULT_TIMEOUT = 25000;
|
|
363
|
-
function getProvider(network, { broviderUrl = DEFAULT_BROVIDER_URL, timeout = DEFAULT_TIMEOUT } = {}) {
|
|
364
|
-
const url = `${broviderUrl}/${network}`;
|
|
365
|
-
if (!providers[network])
|
|
366
|
-
providers[network] = new providers$1.StaticJsonRpcProvider({
|
|
367
|
-
url,
|
|
368
|
-
timeout,
|
|
369
|
-
allowGzip: true
|
|
370
|
-
}, Number(network));
|
|
371
|
-
return providers[network];
|
|
372
|
-
}
|
|
373
|
-
|
|
374
|
-
function signMessage(web3, msg, address) {
|
|
375
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
376
|
-
msg = bytes.hexlify(new Buffer(msg, 'utf8'));
|
|
377
|
-
return yield web3.send('personal_sign', [msg, address]);
|
|
378
|
-
});
|
|
379
|
-
}
|
|
380
|
-
function getBlockNumber(provider) {
|
|
381
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
382
|
-
try {
|
|
383
|
-
const blockNumber = yield provider.getBlockNumber();
|
|
384
|
-
return parseInt(blockNumber);
|
|
385
|
-
}
|
|
386
|
-
catch (e) {
|
|
387
|
-
return Promise.reject();
|
|
388
|
-
}
|
|
389
|
-
});
|
|
390
|
-
}
|
|
391
|
-
|
|
392
|
-
const RPC_URLS = {
|
|
393
|
-
SN_MAIN: 'https://starknet-mainnet.public.blastapi.io',
|
|
394
|
-
SN_SEPOLIA: 'https://starknet-sepolia.public.blastapi.io'
|
|
395
|
-
};
|
|
396
|
-
const ABI = [
|
|
397
|
-
{
|
|
398
|
-
name: 'argent::common::account::IAccount',
|
|
399
|
-
type: 'interface',
|
|
400
|
-
items: [
|
|
401
|
-
{
|
|
402
|
-
name: 'is_valid_signature',
|
|
403
|
-
type: 'function',
|
|
404
|
-
inputs: [
|
|
405
|
-
{
|
|
406
|
-
name: 'hash',
|
|
407
|
-
type: 'core::felt252'
|
|
408
|
-
},
|
|
409
|
-
{
|
|
410
|
-
name: 'signature',
|
|
411
|
-
type: 'core::array::Array::<core::felt252>'
|
|
412
|
-
}
|
|
413
|
-
],
|
|
414
|
-
outputs: [
|
|
415
|
-
{
|
|
416
|
-
type: 'core::felt252'
|
|
417
|
-
}
|
|
418
|
-
],
|
|
419
|
-
state_mutability: 'view'
|
|
420
|
-
}
|
|
421
|
-
]
|
|
422
|
-
}
|
|
423
|
-
];
|
|
424
|
-
function getProvider$1(network, options) {
|
|
425
|
-
var _a;
|
|
426
|
-
if (!RPC_URLS[network])
|
|
427
|
-
throw new Error('Invalid network');
|
|
428
|
-
return new starknet$1.RpcProvider({
|
|
429
|
-
nodeUrl: (_a = options === null || options === void 0 ? void 0 : options.broviderUrl) !== null && _a !== void 0 ? _a : RPC_URLS[network]
|
|
430
|
-
});
|
|
431
|
-
}
|
|
432
|
-
function isStarknetMessage(data) {
|
|
433
|
-
return !!data.primaryType && !!data.types.StarkNetDomain;
|
|
434
|
-
}
|
|
435
|
-
function getHash(data, address) {
|
|
436
|
-
const { domain, types, primaryType, message } = data;
|
|
437
|
-
return starknet$1.typedData.getMessageHash({ types, primaryType, domain, message }, address);
|
|
438
|
-
}
|
|
439
|
-
function verify(address_1, sig_1, data_1) {
|
|
440
|
-
return __awaiter(this, arguments, void 0, function* (address, sig, data, network = 'SN_MAIN', options = {}) {
|
|
441
|
-
try {
|
|
442
|
-
const contractAccount = new starknet$1.Contract(ABI, address, getProvider$1(network, options));
|
|
443
|
-
if (sig.length < 2) {
|
|
444
|
-
throw new Error('Invalid signature format');
|
|
445
|
-
}
|
|
446
|
-
const result = yield contractAccount.is_valid_signature(getHash(data, address), sig.slice(-2));
|
|
447
|
-
return bignumber.BigNumber.from(result).eq(bignumber.BigNumber.from('370462705988'));
|
|
448
|
-
}
|
|
449
|
-
catch (e) {
|
|
450
|
-
if (e.message.includes('Contract not found')) {
|
|
451
|
-
throw new Error('Contract not deployed');
|
|
452
|
-
}
|
|
453
|
-
throw e;
|
|
454
|
-
}
|
|
455
|
-
});
|
|
456
|
-
}
|
|
457
|
-
|
|
458
|
-
var starknet = /*#__PURE__*/Object.freeze({
|
|
459
|
-
__proto__: null,
|
|
460
|
-
isStarknetMessage: isStarknetMessage,
|
|
461
|
-
getHash: getHash,
|
|
462
|
-
'default': verify
|
|
463
|
-
});
|
|
464
|
-
|
|
465
|
-
const ERC6492_DETECTION_SUFFIX = '6492649264926492649264926492649264926492649264926492649264926492';
|
|
466
|
-
function isEqual(a, b) {
|
|
467
|
-
return a.toLowerCase() === b.toLowerCase();
|
|
468
|
-
}
|
|
469
|
-
function getHash$1(data) {
|
|
470
|
-
const { domain, types, message } = data;
|
|
471
|
-
return hash._TypedDataEncoder.hash(domain, types, message);
|
|
472
|
-
}
|
|
473
|
-
function verify$1(address_1, sig_1, data_1) {
|
|
474
|
-
return __awaiter(this, arguments, void 0, function* (address, sig, data, network = '1', options = {}) {
|
|
475
|
-
const { domain, types, message } = data;
|
|
476
|
-
try {
|
|
477
|
-
const recoverAddress = wallet.verifyTypedData(domain, types, message, sig);
|
|
478
|
-
if (isEqual(address, recoverAddress))
|
|
479
|
-
return true;
|
|
480
|
-
}
|
|
481
|
-
catch (e) { }
|
|
482
|
-
const provider = getProvider(network, options);
|
|
483
|
-
const hash = getHash$1(data);
|
|
484
|
-
// Handle EIP-6492
|
|
485
|
-
// https://eips.ethereum.org/EIPS/eip-6492
|
|
486
|
-
//
|
|
487
|
-
// We can actually replace verifyTypedData and verifyDefault with the following code,
|
|
488
|
-
// but https://github.com/AmbireTech/signature-validator/blob/main/contracts/DeploylessUniversalSigValidator.sol
|
|
489
|
-
// also can send an extra network request to the provider. (with verifyTypedData we don't send any extra request)
|
|
490
|
-
//
|
|
491
|
-
if (sig.endsWith(ERC6492_DETECTION_SUFFIX)) {
|
|
492
|
-
try {
|
|
493
|
-
return ('0x01' ===
|
|
494
|
-
(yield provider.call({
|
|
495
|
-
data: bytes.concat([
|
|
496
|
-
'0x60806040523480156200001157600080fd5b50604051620007003803806200070083398101604081905262000034916200056f565b6000620000438484846200004f565b9050806000526001601ff35b600080846001600160a01b0316803b806020016040519081016040528181526000908060200190933c90507f6492649264926492649264926492649264926492649264926492649264926492620000a68462000451565b036200021f57600060608085806020019051810190620000c79190620005ce565b8651929550909350915060000362000192576000836001600160a01b031683604051620000f5919062000643565b6000604051808303816000865af19150503d806000811462000134576040519150601f19603f3d011682016040523d82523d6000602084013e62000139565b606091505b5050905080620001905760405162461bcd60e51b815260206004820152601e60248201527f5369676e617475726556616c696461746f723a206465706c6f796d656e74000060448201526064015b60405180910390fd5b505b604051630b135d3f60e11b808252906001600160a01b038a1690631626ba7e90620001c4908b90869060040162000661565b602060405180830381865afa158015620001e2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200020891906200069d565b6001600160e01b031916149450505050506200044a565b805115620002b157604051630b135d3f60e11b808252906001600160a01b03871690631626ba7e9062000259908890889060040162000661565b602060405180830381865afa15801562000277573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200029d91906200069d565b6001600160e01b031916149150506200044a565b8251604114620003195760405162461bcd60e51b815260206004820152603a6024820152600080516020620006e083398151915260448201527f3a20696e76616c6964207369676e6174757265206c656e677468000000000000606482015260840162000187565b620003236200046b565b506020830151604080850151855186939260009185919081106200034b576200034b620006c9565b016020015160f81c9050601b81148015906200036b57508060ff16601c14155b15620003cf5760405162461bcd60e51b815260206004820152603b6024820152600080516020620006e083398151915260448201527f3a20696e76616c6964207369676e617475726520762076616c75650000000000606482015260840162000187565b6040805160008152602081018083528a905260ff83169181019190915260608101849052608081018390526001600160a01b038a169060019060a0016020604051602081039080840390855afa1580156200042e573d6000803e3d6000fd5b505050602060405103516001600160a01b031614955050505050505b9392505050565b60006020825110156200046357600080fd5b508051015190565b60405180606001604052806003906020820280368337509192915050565b6001600160a01b03811681146200049f57600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b60005b83811015620004d5578181015183820152602001620004bb565b50506000910152565b600082601f830112620004f057600080fd5b81516001600160401b03808211156200050d576200050d620004a2565b604051601f8301601f19908116603f01168101908282118183101715620005385762000538620004a2565b816040528381528660208588010111156200055257600080fd5b62000565846020830160208901620004b8565b9695505050505050565b6000806000606084860312156200058557600080fd5b8351620005928162000489565b6020850151604086015191945092506001600160401b03811115620005b657600080fd5b620005c486828701620004de565b9150509250925092565b600080600060608486031215620005e457600080fd5b8351620005f18162000489565b60208501519093506001600160401b03808211156200060f57600080fd5b6200061d87838801620004de565b935060408601519150808211156200063457600080fd5b50620005c486828701620004de565b6000825162000657818460208701620004b8565b9190910192915050565b828152604060208201526000825180604084015262000688816060850160208701620004b8565b601f01601f1916919091016060019392505050565b600060208284031215620006b057600080fd5b81516001600160e01b0319811681146200044a57600080fd5b634e487b7160e01b600052603260045260246000fdfe5369676e617475726556616c696461746f72237265636f7665725369676e6572',
|
|
497
|
-
new abi.AbiCoder().encode(['address', 'bytes32', 'bytes'], [address, bytes.arrayify(hash), sig])
|
|
498
|
-
])
|
|
499
|
-
})));
|
|
500
|
-
}
|
|
501
|
-
catch (error) {
|
|
502
|
-
return false;
|
|
503
|
-
}
|
|
504
|
-
}
|
|
505
|
-
// Handle EIP-1271
|
|
506
|
-
if (yield verifyDefault(address, sig, hash, provider))
|
|
507
|
-
return true;
|
|
508
|
-
return yield verifyOldVersion(address, sig, hash, provider);
|
|
509
|
-
});
|
|
510
|
-
}
|
|
511
|
-
function verifyDefault(address, sig, hash, provider) {
|
|
512
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
513
|
-
let returnValue;
|
|
514
|
-
const magicValue = '0x1626ba7e';
|
|
515
|
-
const abi = 'function isValidSignature(bytes32 _hash, bytes memory _signature) public view returns (bytes4 magicValue)';
|
|
516
|
-
try {
|
|
517
|
-
returnValue = yield call(provider, [abi], [address, 'isValidSignature', [bytes.arrayify(hash), sig]]);
|
|
518
|
-
}
|
|
519
|
-
catch (e) {
|
|
520
|
-
if (e.message.startsWith('missing revert data in call exception')) {
|
|
521
|
-
return false;
|
|
522
|
-
}
|
|
523
|
-
throw e;
|
|
524
|
-
}
|
|
525
|
-
return isEqual(returnValue, magicValue);
|
|
526
|
-
});
|
|
527
|
-
}
|
|
528
|
-
function verifyOldVersion(address, sig, hash, provider) {
|
|
529
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
530
|
-
const magicValue = '0x20c13b0b';
|
|
531
|
-
const abi = 'function isValidSignature(bytes _hash, bytes memory _signature) public view returns (bytes4 magicValue)';
|
|
532
|
-
const returnValue = yield call(provider, [abi], [address, 'isValidSignature', [bytes.arrayify(hash), sig]]);
|
|
533
|
-
return isEqual(returnValue, magicValue);
|
|
534
|
-
});
|
|
535
|
-
}
|
|
536
|
-
|
|
537
|
-
var evm = /*#__PURE__*/Object.freeze({
|
|
538
|
-
__proto__: null,
|
|
539
|
-
getHash: getHash$1,
|
|
540
|
-
'default': verify$1
|
|
541
|
-
});
|
|
542
|
-
|
|
543
|
-
function getHash$2(data, address) {
|
|
544
|
-
const networkType = isStarknetMessage(data) ? starknet : evm;
|
|
545
|
-
return networkType.getHash(data, address);
|
|
546
|
-
}
|
|
547
|
-
function verify$2(address_1, sig_1, data_1) {
|
|
548
|
-
return __awaiter(this, arguments, void 0, function* (address, sig, data, network = '1', options = {}) {
|
|
549
|
-
if (!isStarknetAddress(address) && !isEvmAddress(address)) {
|
|
550
|
-
throw new Error('Invalid address');
|
|
551
|
-
}
|
|
552
|
-
const networkType = isStarknetMessage(data) ? starknet : evm;
|
|
553
|
-
return yield networkType.default(address, sig, data, network, options);
|
|
554
|
-
});
|
|
555
|
-
}
|
|
556
|
-
|
|
557
|
-
var gateways = [
|
|
558
|
-
"ipfs.snapshot.box",
|
|
559
|
-
"snapshot.4everland.link",
|
|
560
|
-
"ipfs.io",
|
|
561
|
-
"ipfs.fleek.co",
|
|
562
|
-
"gateway.pinata.cloud",
|
|
563
|
-
"dweb.link",
|
|
564
|
-
"ipfs.infura.io"
|
|
565
|
-
];
|
|
566
|
-
|
|
567
333
|
var networks = {
|
|
568
334
|
"1": {
|
|
569
335
|
key: "1",
|
|
@@ -2593,18 +2359,298 @@ var networks = {
|
|
|
2593
2359
|
},
|
|
2594
2360
|
start: 7521509,
|
|
2595
2361
|
logo: "ipfs://QmNnGPr1CNvj12SSGzKARtUHv9FyEfE5nES73U4vBWQSJL"
|
|
2362
|
+
},
|
|
2363
|
+
"0x534e5f4d41494e": {
|
|
2364
|
+
key: "sn",
|
|
2365
|
+
name: "Starknet",
|
|
2366
|
+
shortName: "Starknet",
|
|
2367
|
+
chainId: "0x534e5f4d41494e",
|
|
2368
|
+
network: "mainnet",
|
|
2369
|
+
multicall: "0x05754af3760f3356da99aea5c3ec39ccac7783d925a19666ebbeca58ff0087f4",
|
|
2370
|
+
explorer: {
|
|
2371
|
+
url: "https://starkscan.co"
|
|
2372
|
+
},
|
|
2373
|
+
rpc: [
|
|
2374
|
+
],
|
|
2375
|
+
start: 8446,
|
|
2376
|
+
logo: "ipfs://bafkreihbjafyh7eud7r6e5743esaamifcttsvbspfwcrfoc5ykodjdi67m"
|
|
2377
|
+
},
|
|
2378
|
+
"0x534e5f5345504f4c4941": {
|
|
2379
|
+
key: "sn-sep",
|
|
2380
|
+
name: "Starknet Testnet",
|
|
2381
|
+
shortName: "testnet",
|
|
2382
|
+
chainId: "0x534e5f5345504f4c4941",
|
|
2383
|
+
network: "testnet",
|
|
2384
|
+
testnet: true,
|
|
2385
|
+
multicall: "0x05754af3760f3356da99aea5c3ec39ccac7783d925a19666ebbeca58ff0087f4",
|
|
2386
|
+
explorer: {
|
|
2387
|
+
url: "https://sepolia.starkscan.co"
|
|
2388
|
+
},
|
|
2389
|
+
rpc: [
|
|
2390
|
+
],
|
|
2391
|
+
start: 7,
|
|
2392
|
+
logo: "ipfs://bafkreihbjafyh7eud7r6e5743esaamifcttsvbspfwcrfoc5ykodjdi67m"
|
|
2596
2393
|
}
|
|
2597
2394
|
};
|
|
2598
2395
|
|
|
2599
|
-
|
|
2600
|
-
|
|
2601
|
-
|
|
2602
|
-
|
|
2603
|
-
|
|
2604
|
-
|
|
2396
|
+
const DEFAULT_BROVIDER_URL = 'https://rpc.snapshot.org';
|
|
2397
|
+
const DEFAULT_TIMEOUT = 25000;
|
|
2398
|
+
const STARKNET_BROVIDER_KEYS = ['sn', 'sn-sep'];
|
|
2399
|
+
const providerMemo = new Map();
|
|
2400
|
+
const providerFnMap = {
|
|
2401
|
+
evm: getEvmProvider,
|
|
2402
|
+
starknet: getStarknetProvider
|
|
2403
|
+
};
|
|
2404
|
+
function normalizeOptions(options = {}) {
|
|
2405
|
+
var _a;
|
|
2406
|
+
return {
|
|
2407
|
+
broviderUrl: options.broviderUrl || DEFAULT_BROVIDER_URL,
|
|
2408
|
+
timeout: (_a = options.timeout) !== null && _a !== void 0 ? _a : DEFAULT_TIMEOUT
|
|
2409
|
+
};
|
|
2410
|
+
}
|
|
2411
|
+
function getBroviderNetworkId(network) {
|
|
2412
|
+
const config = networks[network];
|
|
2413
|
+
if (!config) {
|
|
2414
|
+
throw new Error(`Network '${network}' is not supported`);
|
|
2605
2415
|
}
|
|
2606
|
-
|
|
2607
|
-
|
|
2416
|
+
return String(config.key);
|
|
2417
|
+
}
|
|
2418
|
+
function getProviderType(networkId) {
|
|
2419
|
+
const isStarknet = STARKNET_BROVIDER_KEYS.includes(networkId);
|
|
2420
|
+
return isStarknet ? 'starknet' : 'evm';
|
|
2421
|
+
}
|
|
2422
|
+
function createMemoKey(networkId, options) {
|
|
2423
|
+
return `${networkId}:${options.broviderUrl}:${options.timeout}`;
|
|
2424
|
+
}
|
|
2425
|
+
// return loose `any` type to avoid typecheck issues on package consumers
|
|
2426
|
+
function getProvider(network, options = {}) {
|
|
2427
|
+
const networkId = getBroviderNetworkId(network);
|
|
2428
|
+
const normalizedOptions = normalizeOptions(options);
|
|
2429
|
+
const memoKey = createMemoKey(networkId, normalizedOptions);
|
|
2430
|
+
const memoized = providerMemo.get(memoKey);
|
|
2431
|
+
if (memoized) {
|
|
2432
|
+
return memoized;
|
|
2433
|
+
}
|
|
2434
|
+
const providerType = getProviderType(networkId);
|
|
2435
|
+
const provider = providerFnMap[providerType](networkId, normalizedOptions);
|
|
2436
|
+
providerMemo.set(memoKey, provider);
|
|
2437
|
+
return provider;
|
|
2438
|
+
}
|
|
2439
|
+
function getEvmProvider(networkId, options) {
|
|
2440
|
+
return new providers.StaticJsonRpcProvider({
|
|
2441
|
+
url: `${options.broviderUrl}/${networkId}`,
|
|
2442
|
+
timeout: options.timeout,
|
|
2443
|
+
allowGzip: true
|
|
2444
|
+
}, Number(networkId));
|
|
2445
|
+
}
|
|
2446
|
+
function getStarknetProvider(networkKey, options) {
|
|
2447
|
+
return new starknet$1.RpcProvider({
|
|
2448
|
+
nodeUrl: `${options.broviderUrl}/${networkKey}`
|
|
2449
|
+
});
|
|
2450
|
+
}
|
|
2451
|
+
|
|
2452
|
+
function signMessage(web3, msg, address) {
|
|
2453
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
2454
|
+
msg = bytes.hexlify(new Buffer(msg, 'utf8'));
|
|
2455
|
+
return yield web3.send('personal_sign', [msg, address]);
|
|
2456
|
+
});
|
|
2457
|
+
}
|
|
2458
|
+
function getBlockNumber(provider) {
|
|
2459
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
2460
|
+
try {
|
|
2461
|
+
const blockNumber = yield provider.getBlockNumber();
|
|
2462
|
+
return parseInt(blockNumber);
|
|
2463
|
+
}
|
|
2464
|
+
catch (e) {
|
|
2465
|
+
return Promise.reject();
|
|
2466
|
+
}
|
|
2467
|
+
});
|
|
2468
|
+
}
|
|
2469
|
+
|
|
2470
|
+
const RPC_URLS = {
|
|
2471
|
+
SN_MAIN: 'https://starknet-mainnet.public.blastapi.io',
|
|
2472
|
+
SN_SEPOLIA: 'https://starknet-sepolia.public.blastapi.io'
|
|
2473
|
+
};
|
|
2474
|
+
const ABI = [
|
|
2475
|
+
{
|
|
2476
|
+
name: 'argent::common::account::IAccount',
|
|
2477
|
+
type: 'interface',
|
|
2478
|
+
items: [
|
|
2479
|
+
{
|
|
2480
|
+
name: 'is_valid_signature',
|
|
2481
|
+
type: 'function',
|
|
2482
|
+
inputs: [
|
|
2483
|
+
{
|
|
2484
|
+
name: 'hash',
|
|
2485
|
+
type: 'core::felt252'
|
|
2486
|
+
},
|
|
2487
|
+
{
|
|
2488
|
+
name: 'signature',
|
|
2489
|
+
type: 'core::array::Array::<core::felt252>'
|
|
2490
|
+
}
|
|
2491
|
+
],
|
|
2492
|
+
outputs: [
|
|
2493
|
+
{
|
|
2494
|
+
type: 'core::felt252'
|
|
2495
|
+
}
|
|
2496
|
+
],
|
|
2497
|
+
state_mutability: 'view'
|
|
2498
|
+
}
|
|
2499
|
+
]
|
|
2500
|
+
}
|
|
2501
|
+
];
|
|
2502
|
+
function getProvider$1(network, options) {
|
|
2503
|
+
var _a;
|
|
2504
|
+
if (!RPC_URLS[network])
|
|
2505
|
+
throw new Error('Invalid network');
|
|
2506
|
+
return new starknet$1.RpcProvider({
|
|
2507
|
+
nodeUrl: (_a = options === null || options === void 0 ? void 0 : options.broviderUrl) !== null && _a !== void 0 ? _a : RPC_URLS[network]
|
|
2508
|
+
});
|
|
2509
|
+
}
|
|
2510
|
+
function isStarknetMessage(data) {
|
|
2511
|
+
return !!data.primaryType && !!data.types.StarkNetDomain;
|
|
2512
|
+
}
|
|
2513
|
+
function getHash(data, address) {
|
|
2514
|
+
const { domain, types, primaryType, message } = data;
|
|
2515
|
+
return starknet$1.typedData.getMessageHash({ types, primaryType, domain, message }, address);
|
|
2516
|
+
}
|
|
2517
|
+
function verify(address_1, sig_1, data_1) {
|
|
2518
|
+
return __awaiter(this, arguments, void 0, function* (address, sig, data, network = 'SN_MAIN', options = {}) {
|
|
2519
|
+
try {
|
|
2520
|
+
const contractAccount = new starknet$1.Contract(ABI, address, getProvider$1(network, options));
|
|
2521
|
+
if (sig.length < 2) {
|
|
2522
|
+
throw new Error('Invalid signature format');
|
|
2523
|
+
}
|
|
2524
|
+
const result = yield contractAccount.is_valid_signature(getHash(data, address), sig.slice(-2));
|
|
2525
|
+
return bignumber.BigNumber.from(result).eq(bignumber.BigNumber.from('370462705988'));
|
|
2526
|
+
}
|
|
2527
|
+
catch (e) {
|
|
2528
|
+
if (e.message.includes('Contract not found')) {
|
|
2529
|
+
throw new Error('Contract not deployed');
|
|
2530
|
+
}
|
|
2531
|
+
throw e;
|
|
2532
|
+
}
|
|
2533
|
+
});
|
|
2534
|
+
}
|
|
2535
|
+
|
|
2536
|
+
var starknet = /*#__PURE__*/Object.freeze({
|
|
2537
|
+
__proto__: null,
|
|
2538
|
+
isStarknetMessage: isStarknetMessage,
|
|
2539
|
+
getHash: getHash,
|
|
2540
|
+
'default': verify
|
|
2541
|
+
});
|
|
2542
|
+
|
|
2543
|
+
const ERC6492_DETECTION_SUFFIX = '6492649264926492649264926492649264926492649264926492649264926492';
|
|
2544
|
+
function isEqual(a, b) {
|
|
2545
|
+
return a.toLowerCase() === b.toLowerCase();
|
|
2546
|
+
}
|
|
2547
|
+
function getHash$1(data) {
|
|
2548
|
+
const { domain, types, message } = data;
|
|
2549
|
+
return hash._TypedDataEncoder.hash(domain, types, message);
|
|
2550
|
+
}
|
|
2551
|
+
function verify$1(address_1, sig_1, data_1) {
|
|
2552
|
+
return __awaiter(this, arguments, void 0, function* (address, sig, data, network = '1', options = {}) {
|
|
2553
|
+
const { domain, types, message } = data;
|
|
2554
|
+
try {
|
|
2555
|
+
const recoverAddress = wallet.verifyTypedData(domain, types, message, sig);
|
|
2556
|
+
if (isEqual(address, recoverAddress))
|
|
2557
|
+
return true;
|
|
2558
|
+
}
|
|
2559
|
+
catch (e) { }
|
|
2560
|
+
const provider = getProvider(network, options);
|
|
2561
|
+
const hash = getHash$1(data);
|
|
2562
|
+
// Handle EIP-6492
|
|
2563
|
+
// https://eips.ethereum.org/EIPS/eip-6492
|
|
2564
|
+
//
|
|
2565
|
+
// We can actually replace verifyTypedData and verifyDefault with the following code,
|
|
2566
|
+
// but https://github.com/AmbireTech/signature-validator/blob/main/contracts/DeploylessUniversalSigValidator.sol
|
|
2567
|
+
// also can send an extra network request to the provider. (with verifyTypedData we don't send any extra request)
|
|
2568
|
+
//
|
|
2569
|
+
if (sig.endsWith(ERC6492_DETECTION_SUFFIX)) {
|
|
2570
|
+
try {
|
|
2571
|
+
return ('0x01' ===
|
|
2572
|
+
(yield provider.call({
|
|
2573
|
+
data: bytes.concat([
|
|
2574
|
+
'0x60806040523480156200001157600080fd5b50604051620007003803806200070083398101604081905262000034916200056f565b6000620000438484846200004f565b9050806000526001601ff35b600080846001600160a01b0316803b806020016040519081016040528181526000908060200190933c90507f6492649264926492649264926492649264926492649264926492649264926492620000a68462000451565b036200021f57600060608085806020019051810190620000c79190620005ce565b8651929550909350915060000362000192576000836001600160a01b031683604051620000f5919062000643565b6000604051808303816000865af19150503d806000811462000134576040519150601f19603f3d011682016040523d82523d6000602084013e62000139565b606091505b5050905080620001905760405162461bcd60e51b815260206004820152601e60248201527f5369676e617475726556616c696461746f723a206465706c6f796d656e74000060448201526064015b60405180910390fd5b505b604051630b135d3f60e11b808252906001600160a01b038a1690631626ba7e90620001c4908b90869060040162000661565b602060405180830381865afa158015620001e2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200020891906200069d565b6001600160e01b031916149450505050506200044a565b805115620002b157604051630b135d3f60e11b808252906001600160a01b03871690631626ba7e9062000259908890889060040162000661565b602060405180830381865afa15801562000277573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200029d91906200069d565b6001600160e01b031916149150506200044a565b8251604114620003195760405162461bcd60e51b815260206004820152603a6024820152600080516020620006e083398151915260448201527f3a20696e76616c6964207369676e6174757265206c656e677468000000000000606482015260840162000187565b620003236200046b565b506020830151604080850151855186939260009185919081106200034b576200034b620006c9565b016020015160f81c9050601b81148015906200036b57508060ff16601c14155b15620003cf5760405162461bcd60e51b815260206004820152603b6024820152600080516020620006e083398151915260448201527f3a20696e76616c6964207369676e617475726520762076616c75650000000000606482015260840162000187565b6040805160008152602081018083528a905260ff83169181019190915260608101849052608081018390526001600160a01b038a169060019060a0016020604051602081039080840390855afa1580156200042e573d6000803e3d6000fd5b505050602060405103516001600160a01b031614955050505050505b9392505050565b60006020825110156200046357600080fd5b508051015190565b60405180606001604052806003906020820280368337509192915050565b6001600160a01b03811681146200049f57600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b60005b83811015620004d5578181015183820152602001620004bb565b50506000910152565b600082601f830112620004f057600080fd5b81516001600160401b03808211156200050d576200050d620004a2565b604051601f8301601f19908116603f01168101908282118183101715620005385762000538620004a2565b816040528381528660208588010111156200055257600080fd5b62000565846020830160208901620004b8565b9695505050505050565b6000806000606084860312156200058557600080fd5b8351620005928162000489565b6020850151604086015191945092506001600160401b03811115620005b657600080fd5b620005c486828701620004de565b9150509250925092565b600080600060608486031215620005e457600080fd5b8351620005f18162000489565b60208501519093506001600160401b03808211156200060f57600080fd5b6200061d87838801620004de565b935060408601519150808211156200063457600080fd5b50620005c486828701620004de565b6000825162000657818460208701620004b8565b9190910192915050565b828152604060208201526000825180604084015262000688816060850160208701620004b8565b601f01601f1916919091016060019392505050565b600060208284031215620006b057600080fd5b81516001600160e01b0319811681146200044a57600080fd5b634e487b7160e01b600052603260045260246000fdfe5369676e617475726556616c696461746f72237265636f7665725369676e6572',
|
|
2575
|
+
new abi.AbiCoder().encode(['address', 'bytes32', 'bytes'], [address, bytes.arrayify(hash), sig])
|
|
2576
|
+
])
|
|
2577
|
+
})));
|
|
2578
|
+
}
|
|
2579
|
+
catch (error) {
|
|
2580
|
+
return false;
|
|
2581
|
+
}
|
|
2582
|
+
}
|
|
2583
|
+
// Handle EIP-1271
|
|
2584
|
+
if (yield verifyDefault(address, sig, hash, provider))
|
|
2585
|
+
return true;
|
|
2586
|
+
return yield verifyOldVersion(address, sig, hash, provider);
|
|
2587
|
+
});
|
|
2588
|
+
}
|
|
2589
|
+
function verifyDefault(address, sig, hash, provider) {
|
|
2590
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
2591
|
+
let returnValue;
|
|
2592
|
+
const magicValue = '0x1626ba7e';
|
|
2593
|
+
const abi = 'function isValidSignature(bytes32 _hash, bytes memory _signature) public view returns (bytes4 magicValue)';
|
|
2594
|
+
try {
|
|
2595
|
+
returnValue = yield call(provider, [abi], [address, 'isValidSignature', [bytes.arrayify(hash), sig]]);
|
|
2596
|
+
}
|
|
2597
|
+
catch (e) {
|
|
2598
|
+
if (e.message.startsWith('missing revert data in call exception')) {
|
|
2599
|
+
return false;
|
|
2600
|
+
}
|
|
2601
|
+
throw e;
|
|
2602
|
+
}
|
|
2603
|
+
return isEqual(returnValue, magicValue);
|
|
2604
|
+
});
|
|
2605
|
+
}
|
|
2606
|
+
function verifyOldVersion(address, sig, hash, provider) {
|
|
2607
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
2608
|
+
const magicValue = '0x20c13b0b';
|
|
2609
|
+
const abi = 'function isValidSignature(bytes _hash, bytes memory _signature) public view returns (bytes4 magicValue)';
|
|
2610
|
+
const returnValue = yield call(provider, [abi], [address, 'isValidSignature', [bytes.arrayify(hash), sig]]);
|
|
2611
|
+
return isEqual(returnValue, magicValue);
|
|
2612
|
+
});
|
|
2613
|
+
}
|
|
2614
|
+
|
|
2615
|
+
var evm = /*#__PURE__*/Object.freeze({
|
|
2616
|
+
__proto__: null,
|
|
2617
|
+
getHash: getHash$1,
|
|
2618
|
+
'default': verify$1
|
|
2619
|
+
});
|
|
2620
|
+
|
|
2621
|
+
function getHash$2(data, address) {
|
|
2622
|
+
const networkType = isStarknetMessage(data) ? starknet : evm;
|
|
2623
|
+
return networkType.getHash(data, address);
|
|
2624
|
+
}
|
|
2625
|
+
function verify$2(address_1, sig_1, data_1) {
|
|
2626
|
+
return __awaiter(this, arguments, void 0, function* (address, sig, data, network = '1', options = {}) {
|
|
2627
|
+
if (!isStarknetAddress(address) && !isEvmAddress(address)) {
|
|
2628
|
+
throw new Error('Invalid address');
|
|
2629
|
+
}
|
|
2630
|
+
const networkType = isStarknetMessage(data) ? starknet : evm;
|
|
2631
|
+
return yield networkType.default(address, sig, data, network, options);
|
|
2632
|
+
});
|
|
2633
|
+
}
|
|
2634
|
+
|
|
2635
|
+
var gateways = [
|
|
2636
|
+
"ipfs.snapshot.box",
|
|
2637
|
+
"snapshot.4everland.link",
|
|
2638
|
+
"ipfs.io",
|
|
2639
|
+
"ipfs.fleek.co",
|
|
2640
|
+
"gateway.pinata.cloud",
|
|
2641
|
+
"dweb.link",
|
|
2642
|
+
"ipfs.infura.io"
|
|
2643
|
+
];
|
|
2644
|
+
|
|
2645
|
+
class SingleChoiceVoting {
|
|
2646
|
+
constructor(proposal, votes, strategies, selected) {
|
|
2647
|
+
this.proposal = proposal;
|
|
2648
|
+
this.votes = votes;
|
|
2649
|
+
this.strategies = strategies;
|
|
2650
|
+
this.selected = selected;
|
|
2651
|
+
}
|
|
2652
|
+
static isValidChoice(voteChoice, proposalChoices) {
|
|
2653
|
+
return (typeof voteChoice === 'number' &&
|
|
2608
2654
|
(proposalChoices === null || proposalChoices === void 0 ? void 0 : proposalChoices[voteChoice - 1]) !== undefined);
|
|
2609
2655
|
}
|
|
2610
2656
|
getValidVotes() {
|
|
@@ -3193,6 +3239,209 @@ function fetchData(_a) {
|
|
|
3193
3239
|
});
|
|
3194
3240
|
}
|
|
3195
3241
|
|
|
3242
|
+
const multicallAbi = [
|
|
3243
|
+
'function aggregate(tuple(address target, bytes callData)[] calls) view returns (uint256 blockNumber, bytes[] returnData)'
|
|
3244
|
+
];
|
|
3245
|
+
function multicall(address_1, provider_1, abi_1, calls_1, limit_1) {
|
|
3246
|
+
return __awaiter(this, arguments, void 0, function* (address, provider, abi$1, calls, limit, options = {}) {
|
|
3247
|
+
const multi = new contracts.Contract(address, multicallAbi, provider);
|
|
3248
|
+
const itf = new abi.Interface(abi$1);
|
|
3249
|
+
try {
|
|
3250
|
+
const pages = Math.ceil(calls.length / limit);
|
|
3251
|
+
const promises = [];
|
|
3252
|
+
Array.from(Array(pages)).forEach((x, i) => {
|
|
3253
|
+
const callsInPage = calls.slice(limit * i, limit * (i + 1));
|
|
3254
|
+
promises.push(multi.aggregate(callsInPage.map((call) => [
|
|
3255
|
+
call[0].toLowerCase(),
|
|
3256
|
+
itf.encodeFunctionData(call[1], call[2])
|
|
3257
|
+
]), options));
|
|
3258
|
+
});
|
|
3259
|
+
let results = yield Promise.all(promises);
|
|
3260
|
+
results = results.reduce((prev, [, res]) => prev.concat(res), []);
|
|
3261
|
+
return results.map((call, i) => itf.decodeFunctionResult(calls[i][1], call));
|
|
3262
|
+
}
|
|
3263
|
+
catch (e) {
|
|
3264
|
+
return Promise.reject(e);
|
|
3265
|
+
}
|
|
3266
|
+
});
|
|
3267
|
+
}
|
|
3268
|
+
|
|
3269
|
+
/**
|
|
3270
|
+
* Parses the raw result from a Starknet function call based on its ABI.
|
|
3271
|
+
* It handles different types like felt252, u8, u256, etc., and decodes them accordingly.
|
|
3272
|
+
* @param rawResult - The raw result from the Starknet function call.
|
|
3273
|
+
* @param functionAbi - The ABI of the function that was called.
|
|
3274
|
+
* @returns The parsed result in a more usable format.
|
|
3275
|
+
*/
|
|
3276
|
+
function parseStarknetResult(rawResult, functionAbi) {
|
|
3277
|
+
if (!functionAbi ||
|
|
3278
|
+
!functionAbi.outputs ||
|
|
3279
|
+
!Array.isArray(rawResult) ||
|
|
3280
|
+
rawResult.length === 0) {
|
|
3281
|
+
return rawResult;
|
|
3282
|
+
}
|
|
3283
|
+
const output = functionAbi.outputs[0];
|
|
3284
|
+
const rawValue = rawResult[0];
|
|
3285
|
+
try {
|
|
3286
|
+
switch (output.type) {
|
|
3287
|
+
case 'core::felt252':
|
|
3288
|
+
// Try to decode as shortString (for name, symbol)
|
|
3289
|
+
try {
|
|
3290
|
+
return starknet$1.shortString.decodeShortString(rawValue);
|
|
3291
|
+
}
|
|
3292
|
+
catch (_a) {
|
|
3293
|
+
// If shortString decode fails, return as hex
|
|
3294
|
+
return rawValue;
|
|
3295
|
+
}
|
|
3296
|
+
// Unsigned integers
|
|
3297
|
+
case 'core::integer::u8':
|
|
3298
|
+
case 'core::integer::u16':
|
|
3299
|
+
case 'core::integer::u32':
|
|
3300
|
+
case 'core::integer::u64':
|
|
3301
|
+
return parseInt(rawValue, 16);
|
|
3302
|
+
case 'core::integer::u128':
|
|
3303
|
+
case 'core::integer::usize':
|
|
3304
|
+
return BigInt(rawValue).toString();
|
|
3305
|
+
case 'core::integer::u256':
|
|
3306
|
+
return starknet$1.uint256.uint256ToBN({
|
|
3307
|
+
low: rawValue,
|
|
3308
|
+
high: rawResult[1] || '0x0'
|
|
3309
|
+
});
|
|
3310
|
+
// Signed integers
|
|
3311
|
+
case 'core::integer::i8':
|
|
3312
|
+
case 'core::integer::i16':
|
|
3313
|
+
case 'core::integer::i32':
|
|
3314
|
+
case 'core::integer::i64':
|
|
3315
|
+
return parseInt(rawValue, 16);
|
|
3316
|
+
case 'core::integer::i128':
|
|
3317
|
+
return BigInt(rawValue).toString();
|
|
3318
|
+
// Boolean type
|
|
3319
|
+
case 'core::bool':
|
|
3320
|
+
return rawValue === '0x1' || rawValue === '0x01';
|
|
3321
|
+
// Address types
|
|
3322
|
+
case 'core::starknet::contract_address::ContractAddress':
|
|
3323
|
+
case 'core::starknet::class_hash::ClassHash':
|
|
3324
|
+
case 'core::starknet::storage_access::StorageAddress':
|
|
3325
|
+
return rawValue;
|
|
3326
|
+
// Byte array
|
|
3327
|
+
case 'core::bytes_31::bytes31':
|
|
3328
|
+
return rawValue;
|
|
3329
|
+
default:
|
|
3330
|
+
// Return raw value for unknown types
|
|
3331
|
+
return rawValue;
|
|
3332
|
+
}
|
|
3333
|
+
}
|
|
3334
|
+
catch (_b) {
|
|
3335
|
+
// Fallback to raw result if parsing fails
|
|
3336
|
+
return rawResult;
|
|
3337
|
+
}
|
|
3338
|
+
}
|
|
3339
|
+
/**
|
|
3340
|
+
* Partitions the responses from a Starknet multicall into individual call results.
|
|
3341
|
+
* Each response starts with its length, followed by the actual response data.
|
|
3342
|
+
* @param responses - The array of responses from the Starknet multicall.
|
|
3343
|
+
* @returns An array of arrays, where each inner array contains the response data for a single call.
|
|
3344
|
+
*/
|
|
3345
|
+
const partitionResponses = (responses) => {
|
|
3346
|
+
if (responses.length === 0) {
|
|
3347
|
+
return [];
|
|
3348
|
+
}
|
|
3349
|
+
const [responseLength, ...restResponses] = responses;
|
|
3350
|
+
const responseLengthInt = Number(starknet$1.num.toBigInt(responseLength));
|
|
3351
|
+
const response = restResponses.slice(0, responseLengthInt);
|
|
3352
|
+
const remainingResponses = restResponses.slice(responseLengthInt);
|
|
3353
|
+
return [response, ...partitionResponses(remainingResponses)];
|
|
3354
|
+
};
|
|
3355
|
+
function multicall$1(address_1, provider_1, abi_1, calls_1, limit_1) {
|
|
3356
|
+
return __awaiter(this, arguments, void 0, function* (address, provider, abi, calls, limit, options = {}) {
|
|
3357
|
+
const callData = calls.map((call) => {
|
|
3358
|
+
return {
|
|
3359
|
+
contractAddress: call[0],
|
|
3360
|
+
entrypoint: call[1],
|
|
3361
|
+
calldata: call[2] || []
|
|
3362
|
+
};
|
|
3363
|
+
});
|
|
3364
|
+
// Chunk calls into batches based on limit
|
|
3365
|
+
const chunks = [];
|
|
3366
|
+
for (let i = 0; i < callData.length; i += limit) {
|
|
3367
|
+
chunks.push(callData.slice(i, i + limit));
|
|
3368
|
+
}
|
|
3369
|
+
// Process each chunk
|
|
3370
|
+
const paginatedResults = yield Promise.all(chunks.map((chunk) => {
|
|
3371
|
+
var _a;
|
|
3372
|
+
return provider.callContract({
|
|
3373
|
+
contractAddress: address,
|
|
3374
|
+
entrypoint: 'aggregate',
|
|
3375
|
+
calldata: starknet$1.transaction.fromCallsToExecuteCalldata(chunk)
|
|
3376
|
+
}, (_a = options.blockTag) !== null && _a !== void 0 ? _a : 'latest');
|
|
3377
|
+
}));
|
|
3378
|
+
const callResults = paginatedResults
|
|
3379
|
+
.map((callContractResult) => {
|
|
3380
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
3381
|
+
const [_blockNumber, _totalLength, ...results] = callContractResult;
|
|
3382
|
+
return partitionResponses(results);
|
|
3383
|
+
})
|
|
3384
|
+
.flat();
|
|
3385
|
+
return callResults.map((result, index) => {
|
|
3386
|
+
const [, functionName] = calls[index];
|
|
3387
|
+
const functionAbi = abi.find((item) => item.name === functionName);
|
|
3388
|
+
return [parseStarknetResult(result, functionAbi)];
|
|
3389
|
+
});
|
|
3390
|
+
});
|
|
3391
|
+
}
|
|
3392
|
+
|
|
3393
|
+
class Multicaller {
|
|
3394
|
+
constructor(network, provider, abi, options = {}) {
|
|
3395
|
+
this.options = {};
|
|
3396
|
+
this.calls = [];
|
|
3397
|
+
this.paths = [];
|
|
3398
|
+
this.network = network;
|
|
3399
|
+
this.provider = provider;
|
|
3400
|
+
this.abi = abi;
|
|
3401
|
+
this.options = options;
|
|
3402
|
+
}
|
|
3403
|
+
call(path, address, fn, params) {
|
|
3404
|
+
this.calls.push([address, fn, params]);
|
|
3405
|
+
this.paths.push(path);
|
|
3406
|
+
return this;
|
|
3407
|
+
}
|
|
3408
|
+
execute(from) {
|
|
3409
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
3410
|
+
const obj = from || {};
|
|
3411
|
+
const result = yield multicall$2(this.network, this.provider, this.abi, this.calls, this.options);
|
|
3412
|
+
result.forEach((r, i) => set__default['default'](obj, this.paths[i], r.length > 1 ? r : r[0]));
|
|
3413
|
+
this.calls = [];
|
|
3414
|
+
this.paths = [];
|
|
3415
|
+
return obj;
|
|
3416
|
+
});
|
|
3417
|
+
}
|
|
3418
|
+
}
|
|
3419
|
+
|
|
3420
|
+
const STARKNET_CHAIN_IDS = [
|
|
3421
|
+
starknet$1.constants.StarknetChainId.SN_MAIN,
|
|
3422
|
+
starknet$1.constants.StarknetChainId.SN_SEPOLIA
|
|
3423
|
+
];
|
|
3424
|
+
const MULTICALLS_FN = {
|
|
3425
|
+
evm: multicall,
|
|
3426
|
+
starknet: multicall$1
|
|
3427
|
+
};
|
|
3428
|
+
function multicall$2(network_1, provider_1, abi_1, calls_1) {
|
|
3429
|
+
return __awaiter(this, arguments, void 0, function* (network, provider, abi, calls, options = {}) {
|
|
3430
|
+
const address = (options === null || options === void 0 ? void 0 : options.multicallAddress) || networks[network].multicall;
|
|
3431
|
+
if (!address) {
|
|
3432
|
+
throw new Error('missing multicall address');
|
|
3433
|
+
}
|
|
3434
|
+
const multicallOptions = Object.assign({}, options);
|
|
3435
|
+
const limit = (multicallOptions === null || multicallOptions === void 0 ? void 0 : multicallOptions.limit) || 500;
|
|
3436
|
+
delete multicallOptions.limit;
|
|
3437
|
+
delete multicallOptions.multicallAddress;
|
|
3438
|
+
const protocol = STARKNET_CHAIN_IDS.includes(network)
|
|
3439
|
+
? 'starknet'
|
|
3440
|
+
: 'evm';
|
|
3441
|
+
return MULTICALLS_FN[protocol](address, provider, abi, calls, limit, multicallOptions);
|
|
3442
|
+
});
|
|
3443
|
+
}
|
|
3444
|
+
|
|
3196
3445
|
const MUTED_ERRORS = [
|
|
3197
3446
|
// mute error from coinbase, when the subdomain is not found
|
|
3198
3447
|
// most other resolvers just return an empty address
|
|
@@ -3206,16 +3455,6 @@ const ENS_ABI = [
|
|
|
3206
3455
|
'function resolver(bytes32 node) view returns (address)' // ENS registry ABI
|
|
3207
3456
|
];
|
|
3208
3457
|
const EMPTY_ADDRESS = '0x0000000000000000000000000000000000000000';
|
|
3209
|
-
const STARKNET_NETWORKS = {
|
|
3210
|
-
'0x534e5f4d41494e': {
|
|
3211
|
-
name: 'Starknet',
|
|
3212
|
-
testnet: false
|
|
3213
|
-
},
|
|
3214
|
-
'0x534e5f5345504f4c4941': {
|
|
3215
|
-
name: 'Starknet Sepolia',
|
|
3216
|
-
testnet: true
|
|
3217
|
-
}
|
|
3218
|
-
};
|
|
3219
3458
|
const scoreApiHeaders = {
|
|
3220
3459
|
Accept: 'application/json',
|
|
3221
3460
|
'Content-Type': 'application/json'
|
|
@@ -3339,22 +3578,6 @@ ajv.addKeyword({
|
|
|
3339
3578
|
message: 'network not allowed'
|
|
3340
3579
|
}
|
|
3341
3580
|
});
|
|
3342
|
-
ajv.addKeyword({
|
|
3343
|
-
keyword: 'starknetNetwork',
|
|
3344
|
-
validate: function (schema, data) {
|
|
3345
|
-
// @ts-ignore
|
|
3346
|
-
const snapshotEnv = this.snapshotEnv || 'default';
|
|
3347
|
-
if (snapshotEnv === 'mainnet') {
|
|
3348
|
-
return Object.keys(STARKNET_NETWORKS)
|
|
3349
|
-
.filter((id) => !STARKNET_NETWORKS[id].testnet)
|
|
3350
|
-
.includes(data);
|
|
3351
|
-
}
|
|
3352
|
-
return Object.keys(STARKNET_NETWORKS).includes(data);
|
|
3353
|
-
},
|
|
3354
|
-
error: {
|
|
3355
|
-
message: 'network not allowed'
|
|
3356
|
-
}
|
|
3357
|
-
});
|
|
3358
3581
|
// Custom URL format to allow empty string values
|
|
3359
3582
|
// https://github.com/snapshot-labs/snapshot.js/pull/541/files
|
|
3360
3583
|
ajv.addFormat('customUrl', {
|
|
@@ -3423,36 +3646,6 @@ function call(provider, abi, call, options) {
|
|
|
3423
3646
|
}
|
|
3424
3647
|
});
|
|
3425
3648
|
}
|
|
3426
|
-
function multicall(network, provider, abi$1, calls, options) {
|
|
3427
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
3428
|
-
const multicallAbi = [
|
|
3429
|
-
'function aggregate(tuple(address target, bytes callData)[] calls) view returns (uint256 blockNumber, bytes[] returnData)'
|
|
3430
|
-
];
|
|
3431
|
-
const multicallAddress = (options === null || options === void 0 ? void 0 : options.multicallAddress) || networks[network].multicall;
|
|
3432
|
-
const multi = new contracts.Contract(multicallAddress, multicallAbi, provider);
|
|
3433
|
-
const itf = new abi.Interface(abi$1);
|
|
3434
|
-
try {
|
|
3435
|
-
const max = (options === null || options === void 0 ? void 0 : options.limit) || 500;
|
|
3436
|
-
if (options === null || options === void 0 ? void 0 : options.limit)
|
|
3437
|
-
delete options.limit;
|
|
3438
|
-
const pages = Math.ceil(calls.length / max);
|
|
3439
|
-
const promises = [];
|
|
3440
|
-
Array.from(Array(pages)).forEach((x, i) => {
|
|
3441
|
-
const callsInPage = calls.slice(max * i, max * (i + 1));
|
|
3442
|
-
promises.push(multi.aggregate(callsInPage.map((call) => [
|
|
3443
|
-
call[0].toLowerCase(),
|
|
3444
|
-
itf.encodeFunctionData(call[1], call[2])
|
|
3445
|
-
]), options || {}));
|
|
3446
|
-
});
|
|
3447
|
-
let results = yield Promise.all(promises);
|
|
3448
|
-
results = results.reduce((prev, [, res]) => prev.concat(res), []);
|
|
3449
|
-
return results.map((call, i) => itf.decodeFunctionResult(calls[i][1], call));
|
|
3450
|
-
}
|
|
3451
|
-
catch (e) {
|
|
3452
|
-
return Promise.reject(e);
|
|
3453
|
-
}
|
|
3454
|
-
});
|
|
3455
|
-
}
|
|
3456
3649
|
function subgraphRequest(url_1, query_1) {
|
|
3457
3650
|
return __awaiter(this, arguments, void 0, function* (url, query, options = {}) {
|
|
3458
3651
|
const body = { query: jsonToGraphqlQuery.jsonToGraphQLQuery({ query }) };
|
|
@@ -3684,7 +3877,7 @@ function getEnsTextRecord(ens_1, record_1) {
|
|
|
3684
3877
|
[ensHash, record]
|
|
3685
3878
|
]) // Query for text record from each resolver
|
|
3686
3879
|
];
|
|
3687
|
-
const [[resolverAddress], ...textRecords] = yield multicall(network, provider, ENS_ABI, calls, multicallOptions);
|
|
3880
|
+
const [[resolverAddress], ...textRecords] = (yield multicall$2(network, provider, ENS_ABI, calls, multicallOptions));
|
|
3688
3881
|
const resolverIndex = ensResolvers.indexOf(resolverAddress);
|
|
3689
3882
|
return resolverIndex !== -1 ? (_b = textRecords[resolverIndex]) === null || _b === void 0 ? void 0 : _b[0] : null;
|
|
3690
3883
|
});
|
|
@@ -3832,21 +4025,22 @@ function isEvmAddress(address$1) {
|
|
|
3832
4025
|
return address.isAddress(address$1);
|
|
3833
4026
|
}
|
|
3834
4027
|
function getFormattedAddress(address$1, format) {
|
|
3835
|
-
|
|
3836
|
-
|
|
3837
|
-
|
|
4028
|
+
if (typeof address$1 !== 'string' || !/^0[xX]/.test(address$1)) {
|
|
4029
|
+
throw new Error(`Invalid address: ${address$1}`);
|
|
4030
|
+
}
|
|
4031
|
+
const addressType = format !== null && format !== void 0 ? format : (address$1.length === 42 ? 'evm' : 'starknet');
|
|
3838
4032
|
if (addressType === 'evm' && isEvmAddress(address$1))
|
|
3839
4033
|
return address.getAddress(address$1);
|
|
3840
4034
|
if (addressType === 'starknet' && isStarknetAddress(address$1))
|
|
3841
4035
|
return starknet$1.validateAndParseAddress(address$1);
|
|
3842
|
-
throw new Error(`Invalid address: ${address$1}`);
|
|
4036
|
+
throw new Error(`Invalid ${addressType} address: ${address$1}`);
|
|
3843
4037
|
}
|
|
3844
4038
|
function inputError(message) {
|
|
3845
4039
|
return Promise.reject(new Error(message));
|
|
3846
4040
|
}
|
|
3847
4041
|
var utils = {
|
|
3848
4042
|
call,
|
|
3849
|
-
multicall,
|
|
4043
|
+
multicall: multicall$2,
|
|
3850
4044
|
subgraphRequest,
|
|
3851
4045
|
ipfsGet,
|
|
3852
4046
|
getUrl,
|
|
@@ -4136,8 +4330,7 @@ var definitions = {
|
|
|
4136
4330
|
type: "string",
|
|
4137
4331
|
snapshotNetwork: true,
|
|
4138
4332
|
title: "network",
|
|
4139
|
-
minLength: 1
|
|
4140
|
-
maxLength: 32
|
|
4333
|
+
minLength: 1
|
|
4141
4334
|
},
|
|
4142
4335
|
symbol: {
|
|
4143
4336
|
type: "string",
|
|
@@ -4180,7 +4373,6 @@ var definitions = {
|
|
|
4180
4373
|
},
|
|
4181
4374
|
network: {
|
|
4182
4375
|
type: "string",
|
|
4183
|
-
maxLength: 12,
|
|
4184
4376
|
title: "network",
|
|
4185
4377
|
snapshotNetwork: true
|
|
4186
4378
|
},
|
|
@@ -4379,15 +4571,7 @@ var definitions = {
|
|
|
4379
4571
|
type: "string",
|
|
4380
4572
|
title: "Delegation network",
|
|
4381
4573
|
description: "The network of your delegation contract",
|
|
4382
|
-
|
|
4383
|
-
{
|
|
4384
|
-
snapshotNetwork: true
|
|
4385
|
-
},
|
|
4386
|
-
{
|
|
4387
|
-
starknetNetwork: true
|
|
4388
|
-
}
|
|
4389
|
-
],
|
|
4390
|
-
errorMessage: "Must be a valid network"
|
|
4574
|
+
snapshotNetwork: true
|
|
4391
4575
|
},
|
|
4392
4576
|
delegationApi: {
|
|
4393
4577
|
type: "string",
|
|
@@ -4529,15 +4713,7 @@ var definitions = {
|
|
|
4529
4713
|
network: {
|
|
4530
4714
|
type: "string",
|
|
4531
4715
|
title: "Network",
|
|
4532
|
-
|
|
4533
|
-
{
|
|
4534
|
-
snapshotNetwork: true
|
|
4535
|
-
},
|
|
4536
|
-
{
|
|
4537
|
-
starknetNetwork: true
|
|
4538
|
-
}
|
|
4539
|
-
],
|
|
4540
|
-
errorMessage: "Must be a valid network"
|
|
4716
|
+
snapshotNetwork: true
|
|
4541
4717
|
}
|
|
4542
4718
|
},
|
|
4543
4719
|
required: [
|