@show-karma/karma-gap-sdk 0.3.4 → 0.3.6

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.
Files changed (76) hide show
  1. package/core/abi/CommunityResolverABI.json +508 -0
  2. package/core/class/Attestation.js +4 -0
  3. package/core/class/AttestationIPFS.d.ts +7 -0
  4. package/core/class/AttestationIPFS.js +10 -0
  5. package/core/class/GAP.d.ts +7 -0
  6. package/core/class/GAP.js +14 -0
  7. package/core/class/GraphQL/Fetcher.d.ts +132 -0
  8. package/core/class/GraphQL/Fetcher.js +7 -0
  9. package/core/class/GraphQL/GAPFetcher.d.ts +160 -0
  10. package/core/class/GraphQL/GAPFetcher.js +516 -0
  11. package/core/class/IPFS/IPFS.d.ts +13 -0
  12. package/core/class/IPFS/IPFS.js +24 -0
  13. package/core/class/contract/MultiAttest.d.ts +10 -0
  14. package/core/class/contract/MultiAttest.js +19 -0
  15. package/core/class/entities/Milestone.d.ts +2 -0
  16. package/core/class/entities/Milestone.js +4 -0
  17. package/core/class/types/attestations.d.ts +6 -0
  18. package/core/class/types/attestations.js +6 -0
  19. package/core/consts.js +4 -34
  20. package/core/types.d.ts +1 -0
  21. package/package.json +1 -1
  22. package/readme.md +34 -39
  23. package/config/keys.example.json +0 -6
  24. package/core/abi/EAS.json +0 -1
  25. package/core/abi/SchemaRegistry.json +0 -1
  26. package/core/class/Attestation.ts +0 -402
  27. package/core/class/Fetcher.ts +0 -202
  28. package/core/class/GAP.ts +0 -398
  29. package/core/class/GapSchema.ts +0 -90
  30. package/core/class/Gelato/Gelato.ts +0 -286
  31. package/core/class/GraphQL/AxiosGQL.ts +0 -29
  32. package/core/class/GraphQL/EASClient.ts +0 -34
  33. package/core/class/GraphQL/GapEasClient.ts +0 -845
  34. package/core/class/GraphQL/index.ts +0 -3
  35. package/core/class/Schema.ts +0 -609
  36. package/core/class/SchemaError.ts +0 -36
  37. package/core/class/contract/GapContract.ts +0 -353
  38. package/core/class/entities/Community.ts +0 -115
  39. package/core/class/entities/Grant.ts +0 -309
  40. package/core/class/entities/MemberOf.ts +0 -42
  41. package/core/class/entities/Milestone.ts +0 -269
  42. package/core/class/entities/Project.ts +0 -370
  43. package/core/class/entities/index.ts +0 -5
  44. package/core/class/index.ts +0 -10
  45. package/core/class/karma-indexer/GapIndexerClient.ts +0 -245
  46. package/core/class/remote-storage/IpfsStorage.ts +0 -51
  47. package/core/class/remote-storage/RemoteStorage.ts +0 -65
  48. package/core/class/types/attestations.ts +0 -158
  49. package/core/consts.ts +0 -282
  50. package/core/index.ts +0 -7
  51. package/core/scripts/deploy.ts +0 -67
  52. package/core/scripts/index.ts +0 -1
  53. package/core/types.ts +0 -186
  54. package/core/utils/gelato/index.ts +0 -3
  55. package/core/utils/gelato/send-gelato-txn.ts +0 -114
  56. package/core/utils/gelato/sponsor-handler.ts +0 -77
  57. package/core/utils/gelato/watch-gelato-txn.ts +0 -67
  58. package/core/utils/get-date.ts +0 -3
  59. package/core/utils/get-ipfs-data.ts +0 -13
  60. package/core/utils/get-web3-provider.ts +0 -20
  61. package/core/utils/gql-queries.ts +0 -133
  62. package/core/utils/index.ts +0 -7
  63. package/core/utils/map-filter.ts +0 -21
  64. package/core/utils/serialize-bigint.ts +0 -7
  65. package/core/utils/to-unix.ts +0 -18
  66. package/csv-upload/.gitkeep +0 -0
  67. package/csv-upload/example.csv +0 -2
  68. package/csv-upload/scripts/run.ts +0 -193
  69. package/docs/.gitkeep +0 -0
  70. package/docs/images/attestation-architecture.png +0 -0
  71. package/docs/images/dfd-get-projects.png +0 -0
  72. package/index.ts +0 -1
  73. package/schemas/.gitkeep +0 -0
  74. package/schemas/GAP-schemas-1692135812877.json +0 -33
  75. package/test-file.ts +0 -92
  76. package/tsconfig.json +0 -26
package/core/types.ts DELETED
@@ -1,186 +0,0 @@
1
- import { BytesLike } from 'ethers';
2
- import {
3
- AttestationRequestData,
4
- EAS,
5
- MultiAttestationRequest,
6
- SchemaItem,
7
- } from '@ethereum-attestation-service/eas-sdk';
8
- import { SignerOrProvider as EASSigner } from '@ethereum-attestation-service/eas-sdk/dist/transaction';
9
- import { Attestation, GAP } from './class';
10
- import { Fetcher } from './class/Fetcher';
11
- export type Hex = `0x${string}`;
12
-
13
- export type SignerOrProvider = EASSigner & {
14
- address?: Hex;
15
- _address?: Hex;
16
- getAddress?: () => Promise<Hex>;
17
- };
18
-
19
- export interface SchemaInterface<T extends string = string> {
20
- name: string;
21
- schema: SchemaItem[];
22
- references?: T;
23
- uid: Hex;
24
- revocable?: boolean;
25
- }
26
-
27
- export interface MultiRevokeArgs {
28
- uid: Hex;
29
- schemaId: Hex;
30
- }
31
-
32
- export interface AttestArgs<T = unknown> {
33
- to: Hex;
34
- data: T;
35
- refUID?: Hex;
36
- signer: SignerOrProvider;
37
- }
38
-
39
- export type TSchemaName =
40
- | 'Community'
41
- | 'CommunityDetails'
42
- | 'Grant'
43
- | 'GrantDetails'
44
- | 'GrantVerified'
45
- | 'MemberOf'
46
- | 'MemberDetails'
47
- | 'Milestone'
48
- | 'MilestoneCompleted'
49
- | 'MilestoneApproved'
50
- | 'Project'
51
- | 'ProjectDetails'
52
- | 'Details';
53
-
54
- export type TResolvedSchemaNames =
55
- | 'Community'
56
- | 'Grant'
57
- | 'GrantVerified'
58
- | 'MemberOf'
59
- | 'MilestoneCompleted'
60
- | 'MilestoneApproved'
61
- | 'Project'
62
- | 'Details';
63
-
64
- export type TExternalLink =
65
- | 'twitter'
66
- | 'github'
67
- | 'website'
68
- | 'linkedin'
69
- | 'discord';
70
-
71
- export type TNetwork =
72
- // | "mainnet"
73
- // | "base-goerli"
74
- | 'optimism'
75
- | 'optimism-goerli'
76
- | "arbitrum"
77
- | 'sepolia';
78
-
79
- /**
80
- * Generic GAP Facade interface.
81
- * This supplies the GAP class with the necessary properties.
82
- */
83
- export abstract class Facade {
84
- abstract readonly network: TNetwork;
85
- abstract readonly schemas: SchemaInterface[];
86
- abstract readonly fetch: Fetcher;
87
- protected _eas: EAS;
88
-
89
- get eas() {
90
- return this._eas;
91
- }
92
- }
93
-
94
- export interface RawAttestationPayload {
95
- schema: Hex;
96
- data: {
97
- payload: AttestationRequestData;
98
- raw: AttestationRequestData;
99
- };
100
- }
101
-
102
- export interface RawMultiAttestPayload {
103
- payload: MultiAttestData;
104
- raw: MultiAttestData;
105
- }
106
-
107
- export interface MultiAttestData {
108
- uid?: Hex;
109
- multiRequest: MultiAttestationRequest;
110
- refIdx: number;
111
- }
112
-
113
- export type MultiAttestPayload = [Attestation, RawMultiAttestPayload][];
114
-
115
- export interface EASNetworkConfig {
116
- url: string;
117
- rpcUrl: string;
118
- chainId: number;
119
- contracts: {
120
- eas: Hex;
121
- schema: Hex;
122
- multicall: Hex;
123
- projectResolver: Hex;
124
- };
125
- /**
126
- * A tuple containing the schema name and it's UID for that network
127
- */
128
- schemas: Record<TResolvedSchemaNames, Hex>;
129
- }
130
-
131
- export type IGapSchema = SchemaInterface<TSchemaName>;
132
-
133
- export type JSONStr = string;
134
-
135
- export interface Schemata {
136
- uid: Hex;
137
- schema: string;
138
- }
139
-
140
- export interface SchemataRes {
141
- schemata: Schemata[];
142
- }
143
-
144
- export interface IAttestation {
145
- uid: Hex;
146
- attester: Hex;
147
- data: BytesLike;
148
- decodedDataJson: JSONStr;
149
- recipient: Hex;
150
- revoked: boolean;
151
- createdAt: number;
152
- refUID?: Hex;
153
- isOffchain: boolean;
154
- revocable: boolean;
155
- revocationTime?: number;
156
- schemaId: Hex;
157
- }
158
-
159
- export interface AttestationRes {
160
- attestation: IAttestation;
161
- }
162
-
163
- export interface AttestationsRes {
164
- attestations: IAttestation[];
165
- }
166
-
167
- export interface SchemaRes {
168
- schema: {
169
- attestations: IAttestation[];
170
- };
171
- }
172
-
173
- /**
174
- * Valid remote storage types
175
- */
176
- export const enum STORAGE_TYPE {
177
- IPFS = 0,
178
- ARWEAVE = 1,
179
- SWARM = 2,
180
- UNKNOWN = 3,
181
- }
182
-
183
- export type TRemoteStorageOutput<T = unknown> = {
184
- hash: T;
185
- storageType: number;
186
- };
@@ -1,3 +0,0 @@
1
- export * from './send-gelato-txn';
2
- export * from './sponsor-handler';
3
- export * from './watch-gelato-txn';
@@ -1,114 +0,0 @@
1
- import axios from 'axios';
2
- import { GelatoRelay } from '@gelatonetwork/relay-sdk';
3
- import { watchGelatoTxn } from './watch-gelato-txn';
4
- import { GAP } from '../../class/GAP';
5
- import { Hex } from '../../types';
6
-
7
- async function sendByUrl(...params: Parameters<GelatoRelay['sponsoredCall']>) {
8
- const { data } = await axios.post<string>(GAP.gelatoOpts.sponsorUrl, params);
9
- return data;
10
- }
11
-
12
- /**
13
- * Send gelato using an explicit api key.
14
- *
15
- * > __This is not safe in the frontend.__
16
- *
17
- * @param params
18
- * @returns Gelato's task id and a wait function.
19
- */
20
- async function sendByApiKey(
21
- ...params: Parameters<GelatoRelay['sponsoredCall']>
22
- ) {
23
- const { apiKey } = GAP?.gelatoOpts || {};
24
-
25
- if (!apiKey && params[1] === '{apiKey}')
26
- throw new Error('No api key provided.');
27
-
28
- if (apiKey && params[1] === '{apiKey}') params[1] = apiKey;
29
-
30
- const client = new GelatoRelay();
31
- const relayResponse = await client.sponsoredCall(...params);
32
-
33
- return {
34
- taskId: relayResponse.taskId,
35
- /**
36
- * Waits for the transaction to be confirmed by Gelato.
37
- * @param ttl interval between checks in ms
38
- * @returns Txn id
39
- */
40
- wait: (ttl?: number) => watchGelatoTxn(relayResponse.taskId, ttl),
41
- };
42
- }
43
-
44
- /**
45
- * Sends a sponsored call using GelatoRelay
46
- * @param payload
47
- * @returns txn hash
48
- */
49
- async function sendGelatoTxn(
50
- ...params: Parameters<GelatoRelay['sponsoredCall']>
51
- ) {
52
- if (!GAP.gelatoOpts) throw new Error('Gelato opts not set.');
53
- const { env_gelatoApiKey, sponsorUrl, useGasless, contained } =
54
- GAP.gelatoOpts;
55
-
56
- if (!useGasless) throw new Error('Gasless is not enabled.');
57
-
58
- if (
59
- (sponsorUrl && contained && env_gelatoApiKey) ||
60
- (sponsorUrl && !contained)
61
- ) {
62
- return sendByUrl(...params);
63
- }
64
-
65
- const { wait } = await sendByApiKey(...params);
66
- return wait();
67
- }
68
-
69
- /**
70
- * Builds the arguments for a sponsored call using GelatoRelay
71
- * @param data Populated contract call.
72
- * @param chainId
73
- * @param target target contract address (Hex)
74
- *
75
- * @example
76
- *
77
- * ```ts
78
- * const { data } = await contract.populateTransaction.transfer(
79
- * recipient,
80
- * amount
81
- * );
82
- * const args = buildArgs(data, chainId, target);
83
- * const txn = sendGelatoTxn(...args);
84
- * console.log(txn) // 0xabc..
85
- * ```
86
- */
87
- function buildArgs(
88
- /**
89
- * Populated transaction data.
90
- */
91
- data: string,
92
- chainId: bigint,
93
- target: Hex
94
- ): Parameters<GelatoRelay['sponsoredCall']> {
95
- return [
96
- {
97
- data,
98
- chainId,
99
- target,
100
- },
101
- '{apiKey}', // filled in the api
102
- {
103
- retries: 3,
104
- },
105
- ];
106
- }
107
-
108
- const Gelato = {
109
- sendByApiKey,
110
- sendByUrl,
111
- buildArgs,
112
- };
113
-
114
- export { sendGelatoTxn, Gelato };
@@ -1,77 +0,0 @@
1
- import { GelatoRelay } from "@gelatonetwork/relay-sdk";
2
- import { GAP } from "../../class/GAP";
3
- import { Gelato, sendGelatoTxn } from "./send-gelato-txn";
4
-
5
- export interface ApiRequest {
6
- method: string;
7
- body: unknown;
8
- }
9
-
10
- export interface ApiResponse {
11
- statusCode: number;
12
- send: (body: unknown) => void;
13
- }
14
-
15
- const assertionObj = [
16
- {
17
- data: /0x[a-fA-F0-9]+/gim,
18
- chainId: /\d+/,
19
- target: /0x[a-fA-F0-9]{40}/gim,
20
- },
21
- /\{apiKey\}/,
22
- {
23
- retries: /\d+/,
24
- },
25
- ];
26
-
27
- function assert(body: any): body is Parameters<GelatoRelay["sponsoredCall"]> {
28
- if (!Array.isArray(body) || body.length !== assertionObj.length)
29
- throw new Error("Invalid request body");
30
-
31
- assertionObj.forEach((item, index) => {
32
- // check if objects from assertion Object are present in body
33
- // and test them using the regexp from the assertion Object
34
- if (typeof item === "object") {
35
- Object.entries(item).forEach(([key, value]) => {
36
- if (!body[index][key]?.toString().match(value))
37
- throw new Error("Invalid request body");
38
- });
39
- }
40
- // test other items as strings
41
- else if (!body[index]?.toString().match(item))
42
- throw new Error("Invalid request body");
43
- });
44
-
45
- return true;
46
- }
47
-
48
- export async function handler(
49
- req: ApiRequest,
50
- res: ApiResponse,
51
- env_gelatoApiKey: string
52
- ) {
53
- if (req.method !== "POST") {
54
- res.statusCode = 405;
55
- res.send("Method not allowed");
56
- return;
57
- }
58
- try {
59
- const body = req.body as unknown;
60
-
61
- if (!assert(body)) return;
62
-
63
- const { [env_gelatoApiKey]: apiKey } = process.env;
64
- if (!apiKey) throw new Error("Api key not provided.");
65
- body[1] = apiKey;
66
-
67
- const result = await Gelato.sendByApiKey(...body);
68
- const txId = await result.wait();
69
- res.send(txId);
70
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
71
- } catch (error: any) {
72
- // eslint-disable-next-line no-console
73
- console.log(error);
74
- res.statusCode = 400;
75
- res.send(error.message);
76
- }
77
- }
@@ -1,67 +0,0 @@
1
- import { GelatoRelay } from '@gelatonetwork/relay-sdk';
2
-
3
- enum TaskState {
4
- CheckPending = 'CheckPending',
5
- ExecPending = 'ExecPending',
6
- ExecSuccess = 'ExecSuccess',
7
- ExecReverted = 'ExecReverted',
8
- WaitingForConfirmation = 'WaitingForConfirmation',
9
- Blacklisted = 'Blacklisted',
10
- Cancelled = 'Cancelled',
11
- NotFound = 'NotFound',
12
- }
13
-
14
- /**
15
- * Waits for a transaction to be mined at Gelato Network
16
- * @param taskId
17
- * @returns
18
- */
19
- async function watchGelatoTxn(taskId: string, ttl = 500): Promise<string> {
20
- const client = new GelatoRelay();
21
- return new Promise((resolve, reject) => {
22
- const loop = async () => {
23
- const oneSecond = 1;
24
- try {
25
- while (oneSecond) {
26
- const status = await client.getTaskStatus(taskId);
27
- // print status :D so we can debug this for now
28
- // eslint-disable-next-line no-console
29
- console.log(status);
30
- if (!status) {
31
- reject(new Error('Transaction goes wrong.'));
32
- break;
33
- }
34
- if (status && status.taskState === TaskState.ExecSuccess) {
35
- resolve(status.transactionHash || '');
36
- break;
37
- } else if (
38
- [
39
- TaskState.Cancelled,
40
- TaskState.ExecReverted,
41
- TaskState.Blacklisted,
42
- ].includes(status?.taskState)
43
- ) {
44
- reject(
45
- new Error(
46
- status.lastCheckMessage
47
- ?.split(/(RegisterDelegate)|(Execution error): /)
48
- .at(-1) || ''
49
- )
50
- );
51
- break;
52
- }
53
-
54
- await new Promise((r) => setTimeout(r, ttl));
55
- }
56
- } catch {
57
- // gelato may throw 429 error, so we need to retry
58
- // Increase ttl to avoid too deadlocking
59
- // Max ttl is 30s
60
- ttl += Math.max(30000, ttl + 1000);
61
- }
62
- };
63
- loop();
64
- });
65
- }
66
-
67
- export { watchGelatoTxn };
@@ -1,3 +0,0 @@
1
- export function getDate(date: Date | number) {
2
- return typeof date === "number" ? new Date(date * 1000) : date;
3
- }
@@ -1,13 +0,0 @@
1
- import axios from 'axios';
2
-
3
- export async function getIPFSData<T>(cid: string): Promise<T> {
4
- try {
5
- const { data } = await axios.get(`https://ipfs.io/ipfs/${cid}`, {
6
- timeout: 5000,
7
- });
8
- return data as T;
9
- } catch (err) {
10
- console.error(err);
11
- throw new Error(`Error to retrive data for CID: ${cid}`);
12
- }
13
- }
@@ -1,20 +0,0 @@
1
- import { Networks } from '../consts';
2
- import { ethers } from 'ethers';
3
-
4
- const providers: Record<number, ethers.providers.JsonRpcProvider> = {};
5
-
6
- export const getWeb3Provider = (
7
- chainId: number
8
- ): ethers.providers.JsonRpcProvider => {
9
- const rpcUrl = Object.values(Networks).find((n) => n.chainId === chainId)
10
- ?.rpcUrl;
11
-
12
- if (!rpcUrl) {
13
- throw new Error(`No rpcUrl found for chainId ${chainId}`);
14
- }
15
-
16
- if (!providers[chainId]) {
17
- providers[chainId] = new ethers.providers.JsonRpcProvider(rpcUrl);
18
- }
19
- return providers[chainId];
20
- };
@@ -1,133 +0,0 @@
1
- import { nullRef } from "../consts";
2
- import { Hex } from "../types";
3
-
4
- const inStatement = (values: (string | number)[]) =>
5
- `[${values.map((v) => `"${v}"`).join(",")}]`;
6
-
7
- const attestationFields = `
8
- uid: id
9
- attester
10
- data
11
- decodedDataJson
12
- recipient
13
- revoked
14
- createdAt: timeCreated
15
- refUID
16
- isOffchain
17
- revocable
18
- revocationTime
19
- schemaId
20
- `;
21
-
22
- const schemaQuery = (schemaId: Hex, content: string) =>
23
- `{schema(where: {id: "${schemaId}"}) {${content}}}`;
24
-
25
- export const gqlQueries = {
26
- attestation: (uid: Hex) => `
27
- {
28
- attestation(where: {
29
- id: "${uid}"
30
- }) {${attestationFields}}
31
- }`,
32
- attestations: (schemaId: Hex, uid: Hex) =>
33
- schemaQuery(
34
- schemaId,
35
- `attestations(where: {
36
- revoked: {equals: false}
37
- decodedDataJson: {contains: "${uid}"}
38
- }) {${attestationFields}}`
39
- ),
40
- attestationsIn: (uids: Hex[], search?: string) => `
41
- {
42
- attestations(where: {
43
- id:{in: ${inStatement(uids)}}
44
- revoked:{equals:false}
45
- ${
46
- search
47
- ? `decodedDataJson:{contains:"${search}",mode:insensitive}`
48
- : ""
49
- }
50
- }) {${attestationFields}}
51
- }`,
52
- attestationsFrom: (schemaId: Hex, attester: Hex) =>
53
- schemaQuery(
54
- schemaId,
55
- `attestations(orderBy:{timeCreated: desc},
56
- where:{attester:{equals:"${attester}"}
57
- revoked:{equals:false}
58
- }){${attestationFields}}`
59
- ),
60
- attestationsTo: (schemaId: Hex, recipient: Hex) =>
61
- schemaQuery(
62
- schemaId,
63
- `attestations(orderBy:{timeCreated: desc},
64
- where:{
65
- recipient:{equals:"${recipient}"}
66
- revoked:{equals:false}
67
- }){${attestationFields}}`
68
- ),
69
- attestationPairs: (schemaId: Hex, attester: Hex, recipient: Hex) =>
70
- schemaQuery(
71
- schemaId,
72
- `attestations(where: {
73
- attester: {equals: "${attester}"}
74
- recipient: {equals: "${recipient}"}
75
- revoked: {equals: false}
76
- }) {${attestationFields}}`
77
- ),
78
- attestationsOf: (
79
- schemaId: Hex,
80
- search?: string[] | string,
81
- refUids?: Hex[]
82
- ) =>
83
- schemaQuery(
84
- schemaId,
85
- `attestations(orderBy:{timeCreated: desc},
86
- where: {
87
- revoked:{equals:false}
88
- ${
89
- refUids && refUids.length
90
- ? `refUID:{in: ${inStatement(refUids)}}`
91
- : ""
92
- }
93
- ${
94
- search
95
- ? `OR: [
96
- ${[search]
97
- .flat()
98
- .map(
99
- (s) =>
100
- `{decodedDataJson:{contains:"${s}",mode:insensitive}}`
101
- )
102
- .join(",")}
103
- ]`
104
- : ""
105
- }
106
- })
107
- {${attestationFields}}`
108
- ),
109
-
110
- dependentsOf: (
111
- refs: Hex | Hex[],
112
- schemaIds: Hex[],
113
- attesters: Hex[] = []
114
- ) => `
115
- {
116
- attestations(
117
- orderBy:{timeCreated: desc},
118
- where: {
119
- refUID:{in: ${inStatement([refs].flat())}}
120
- revoked:{equals: false}
121
- schemaId:{in: ${inStatement(schemaIds)}}
122
- ${attesters.length ? `attester:{in:${inStatement(attesters)}}` : ""}
123
- }){${attestationFields}}
124
- }
125
- `,
126
- schemata: (creator: Hex) => `
127
- {
128
- schemata(where: {creator: {equals: "${creator}"}}) {
129
- uid: id
130
- schema
131
- }
132
- }`,
133
- };
@@ -1,7 +0,0 @@
1
- export * from './gelato';
2
- export * from './get-date';
3
- export * from './gql-queries';
4
- export * from './map-filter';
5
- export * from './serialize-bigint';
6
- export * from './to-unix';
7
- export * from './get-ipfs-data';
@@ -1,21 +0,0 @@
1
- /**
2
- * Filters an array by its condition then maps it to the desired format.
3
- * @param arr
4
- * @param condition
5
- * @param mapTo
6
- * @returns
7
- */
8
- export function mapFilter<T = unknown, U = unknown>(
9
- arr: U[],
10
- condition: (item: U) => boolean,
11
- mapTo: (item: U) => T
12
- ): T[] {
13
- const newArray: T[] = [];
14
-
15
- for (const item of arr) {
16
- if (condition(item)) {
17
- newArray.push(mapTo(item));
18
- }
19
- }
20
- return newArray;
21
- }
@@ -1,7 +0,0 @@
1
- export function serializeWithBigint(value: unknown) {
2
- return JSON.stringify(
3
- value,
4
- (this,
5
- (key, value) => (typeof value === "bigint" ? value.toString() : value))
6
- );
7
- }
@@ -1,18 +0,0 @@
1
- export function toUnix(value: number | Date | string) {
2
- switch (typeof value) {
3
- case "number":
4
- value = Math.round(value);
5
- if (value.toString().length > 13)
6
- throw new Error("Invalid timestamp length");
7
- if (value.toString().length === 10) return value;
8
- return Math.floor(value / 1000);
9
- case "string":
10
- if (/\D/.test(value)) return null;
11
- return toUnix(+value);
12
- case "object":
13
- if (value instanceof Date) return toUnix(value.getTime());
14
- return null;
15
- default:
16
- return null;
17
- }
18
- }
File without changes
@@ -1,2 +0,0 @@
1
- URL,Owner,Twitter,Github,Website,"Project Description","If you've participated in past grant rounds, please share any new updates or milestones from the prior months",How do you measure the impact of your project?
2
- https://explorer.gitcoin.co/#/round/424/0x222ea76664ed77d18d4416d2b2e77937b76f0a35/0x222ea76664ed77d18d4416d2b2e77937b76f0a35-5,ethdotlimo.eth,https://eth.limo,https://github.com/ethlimo,https://eth.limo,"eth.limo is a privacy-preserving ENS gateway, enabling users to access Ethereum-native dApps and content. LIMO represents a shift in dweb adoption by providing an alternative means of accessing ENS resolvable domains.","Support for .art ENS domain resolution, maintained 100% uptime, 1w3.eth content pinning - this ensures fast and reliable access to ENS domain data, with multiple storage locations and a streamlined gateway to IPFS for improved speed and availability. We're also working on some back-end improvements.",