@graphprotocol/graph-cli 0.96.0 → 0.96.1-alpha-20250227201537-7fda6f366205e455e0af20f7f8499fc4f6938f96
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/CHANGELOG.md +16 -0
- package/dist/codegen/schema.d.ts +7 -6
- package/dist/codegen/schema.js +76 -7
- package/dist/codegen/schema.test.js +123 -0
- package/dist/command-helpers/contracts.js +2 -2
- package/dist/command-helpers/spinner.js +1 -1
- package/dist/command-helpers/subgraph.d.ts +1 -0
- package/dist/command-helpers/subgraph.js +3 -0
- package/dist/command-helpers/subgraph.test.d.ts +1 -0
- package/dist/command-helpers/subgraph.test.js +41 -0
- package/dist/commands/init.js +20 -18
- package/dist/scaffold/ethereum.test.js +1 -0
- package/dist/scaffold/mapping.js +3 -2
- package/dist/scaffold/schema.js +4 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/oclif.manifest.json +1 -1
- package/package.json +4 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# @graphprotocol/graph-cli
|
|
2
2
|
|
|
3
|
+
## 0.96.1-alpha-20250227201537-7fda6f366205e455e0af20f7f8499fc4f6938f96
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#1969](https://github.com/graphprotocol/graph-tooling/pull/1969) [`5ffce65`](https://github.com/graphprotocol/graph-tooling/commit/5ffce651d11a68b8eae743785311eac74c8da563) Thanks [@YaroShkvorets](https://github.com/YaroShkvorets)! - handle sized arrays in abi when changetype
|
|
8
|
+
|
|
9
|
+
- [#1967](https://github.com/graphprotocol/graph-tooling/pull/1967) [`388ee5a`](https://github.com/graphprotocol/graph-tooling/commit/388ee5a52a150bcd1ce544278f85242ea0498dcf) Thanks [@YaroShkvorets](https://github.com/YaroShkvorets)! - show sourcify fetch status
|
|
10
|
+
|
|
11
|
+
- [#1934](https://github.com/graphprotocol/graph-tooling/pull/1934) [`30f2aa5`](https://github.com/graphprotocol/graph-tooling/commit/30f2aa500db1b708f38ba6ee7ce7b0e7660cc40b) Thanks [@shiyasmohd](https://github.com/shiyasmohd)! - fix: generate types for mappings when int8 is used as id
|
|
12
|
+
|
|
13
|
+
- [#1971](https://github.com/graphprotocol/graph-tooling/pull/1971) [`4e2b689`](https://github.com/graphprotocol/graph-tooling/commit/4e2b689d90e91b40b6bb4b0af76e42973582ebf7) Thanks [@YaroShkvorets](https://github.com/YaroShkvorets)! - `graph codegen`: fix bug with id field clash in example entity
|
|
14
|
+
|
|
15
|
+
- [#1966](https://github.com/graphprotocol/graph-tooling/pull/1966) [`84b0d21`](https://github.com/graphprotocol/graph-tooling/commit/84b0d21f60da67295d41f096211d31cd0cd432cb) Thanks [@YaroShkvorets](https://github.com/YaroShkvorets)! - handle invalid characters in contract name #1883
|
|
16
|
+
|
|
17
|
+
- [#1974](https://github.com/graphprotocol/graph-tooling/pull/1974) [`31c25e7`](https://github.com/graphprotocol/graph-tooling/commit/31c25e74569035209e768332556ad358cb11258d) Thanks [@YaroShkvorets](https://github.com/YaroShkvorets)! - handle non-standard Etherscan API responses, i.e. kaia
|
|
18
|
+
|
|
3
19
|
## 0.96.0
|
|
4
20
|
|
|
5
21
|
### Minor Changes
|
package/dist/codegen/schema.d.ts
CHANGED
|
@@ -4,15 +4,16 @@ import * as tsCodegen from './typescript.js';
|
|
|
4
4
|
declare class IdField {
|
|
5
5
|
static BYTES: symbol;
|
|
6
6
|
static STRING: symbol;
|
|
7
|
+
static INT8: symbol;
|
|
7
8
|
private kind;
|
|
8
9
|
constructor(idField: FieldDefinitionNode | undefined);
|
|
9
|
-
typeName(): "string" | "Bytes";
|
|
10
|
-
gqlTypeName(): "Bytes" | "String";
|
|
10
|
+
typeName(): "string" | "Bytes" | "Int8";
|
|
11
|
+
gqlTypeName(): "Bytes" | "Int8" | "String";
|
|
11
12
|
tsNamedType(): tsCodegen.NamedType;
|
|
12
|
-
tsValueFrom(): "Value.fromBytes(id)" | "Value.fromString(id)";
|
|
13
|
-
tsValueKind(): "ValueKind.BYTES" | "ValueKind.STRING";
|
|
14
|
-
tsValueToString(): "id.toBytes().toHexString()" | "id.toString()";
|
|
15
|
-
tsToString(): "id.toHexString()" | "id";
|
|
13
|
+
tsValueFrom(): "Value.fromBytes(id)" | "Value.fromI64(id)" | "Value.fromString(id)";
|
|
14
|
+
tsValueKind(): "ValueKind.BYTES" | "ValueKind.INT8" | "ValueKind.STRING";
|
|
15
|
+
tsValueToString(): "id.toBytes().toHexString()" | "id.toI64().toString()" | "id.toString()";
|
|
16
|
+
tsToString(): "id.toString()" | "id.toHexString()" | "id";
|
|
16
17
|
static fromFields(fields: readonly FieldDefinitionNode[] | undefined): IdField;
|
|
17
18
|
static fromTypeDef(def: ObjectTypeDefinitionNode | InterfaceTypeDefinitionNode): IdField;
|
|
18
19
|
}
|
package/dist/codegen/schema.js
CHANGED
|
@@ -5,6 +5,7 @@ import * as util from './util.js';
|
|
|
5
5
|
class IdField {
|
|
6
6
|
static BYTES = Symbol('Bytes');
|
|
7
7
|
static STRING = Symbol('String');
|
|
8
|
+
static INT8 = Symbol('Int8');
|
|
8
9
|
kind;
|
|
9
10
|
constructor(idField) {
|
|
10
11
|
if (idField?.type.kind !== 'NonNullType') {
|
|
@@ -14,28 +15,95 @@ class IdField {
|
|
|
14
15
|
throw Error('id field must be a named type');
|
|
15
16
|
}
|
|
16
17
|
const typeName = idField.type.type.name.value;
|
|
17
|
-
|
|
18
|
+
switch (typeName) {
|
|
19
|
+
case 'Bytes':
|
|
20
|
+
this.kind = IdField.BYTES;
|
|
21
|
+
break;
|
|
22
|
+
case 'Int8':
|
|
23
|
+
this.kind = IdField.INT8;
|
|
24
|
+
break;
|
|
25
|
+
case 'String':
|
|
26
|
+
this.kind = IdField.STRING;
|
|
27
|
+
break;
|
|
28
|
+
default:
|
|
29
|
+
this.kind = IdField.STRING;
|
|
30
|
+
break;
|
|
31
|
+
}
|
|
18
32
|
}
|
|
19
33
|
typeName() {
|
|
20
|
-
|
|
34
|
+
switch (this.kind) {
|
|
35
|
+
case IdField.BYTES:
|
|
36
|
+
return 'Bytes';
|
|
37
|
+
case IdField.INT8:
|
|
38
|
+
return 'Int8';
|
|
39
|
+
case IdField.STRING:
|
|
40
|
+
return 'string';
|
|
41
|
+
default:
|
|
42
|
+
return 'string';
|
|
43
|
+
}
|
|
21
44
|
}
|
|
22
45
|
gqlTypeName() {
|
|
23
|
-
|
|
46
|
+
switch (this.kind) {
|
|
47
|
+
case IdField.BYTES:
|
|
48
|
+
return 'Bytes';
|
|
49
|
+
case IdField.INT8:
|
|
50
|
+
return 'Int8';
|
|
51
|
+
case IdField.STRING:
|
|
52
|
+
return 'String';
|
|
53
|
+
default:
|
|
54
|
+
return 'String';
|
|
55
|
+
}
|
|
24
56
|
}
|
|
25
57
|
tsNamedType() {
|
|
26
58
|
return tsCodegen.namedType(this.typeName());
|
|
27
59
|
}
|
|
28
60
|
tsValueFrom() {
|
|
29
|
-
|
|
61
|
+
switch (this.kind) {
|
|
62
|
+
case IdField.BYTES:
|
|
63
|
+
return 'Value.fromBytes(id)';
|
|
64
|
+
case IdField.INT8:
|
|
65
|
+
return 'Value.fromI64(id)';
|
|
66
|
+
case IdField.STRING:
|
|
67
|
+
return 'Value.fromString(id)';
|
|
68
|
+
default:
|
|
69
|
+
return 'Value.fromString(id)';
|
|
70
|
+
}
|
|
30
71
|
}
|
|
31
72
|
tsValueKind() {
|
|
32
|
-
|
|
73
|
+
switch (this.kind) {
|
|
74
|
+
case IdField.BYTES:
|
|
75
|
+
return 'ValueKind.BYTES';
|
|
76
|
+
case IdField.INT8:
|
|
77
|
+
return 'ValueKind.INT8';
|
|
78
|
+
case IdField.STRING:
|
|
79
|
+
return 'ValueKind.STRING';
|
|
80
|
+
default:
|
|
81
|
+
return 'ValueKind.STRING';
|
|
82
|
+
}
|
|
33
83
|
}
|
|
34
84
|
tsValueToString() {
|
|
35
|
-
|
|
85
|
+
switch (this.kind) {
|
|
86
|
+
case IdField.BYTES:
|
|
87
|
+
return 'id.toBytes().toHexString()';
|
|
88
|
+
case IdField.INT8:
|
|
89
|
+
return 'id.toI64().toString()';
|
|
90
|
+
case IdField.STRING:
|
|
91
|
+
return 'id.toString()';
|
|
92
|
+
default:
|
|
93
|
+
return 'id.toString()';
|
|
94
|
+
}
|
|
36
95
|
}
|
|
37
96
|
tsToString() {
|
|
38
|
-
|
|
97
|
+
switch (this.kind) {
|
|
98
|
+
case IdField.BYTES:
|
|
99
|
+
return 'id.toHexString()';
|
|
100
|
+
case IdField.INT8:
|
|
101
|
+
return 'id.toString()';
|
|
102
|
+
case IdField.STRING:
|
|
103
|
+
return 'id';
|
|
104
|
+
default:
|
|
105
|
+
return 'id';
|
|
106
|
+
}
|
|
39
107
|
}
|
|
40
108
|
static fromFields(fields) {
|
|
41
109
|
const idField = fields?.find(field => field.name.value === 'id');
|
|
@@ -66,6 +134,7 @@ export default class SchemaCodeGenerator {
|
|
|
66
134
|
'Bytes',
|
|
67
135
|
'BigInt',
|
|
68
136
|
'BigDecimal',
|
|
137
|
+
'Int8',
|
|
69
138
|
], '@graphprotocol/graph-ts'),
|
|
70
139
|
];
|
|
71
140
|
}
|
|
@@ -559,6 +559,129 @@ describe('Schema code generator', { concurrent: true }, () => {
|
|
|
559
559
|
],
|
|
560
560
|
});
|
|
561
561
|
});
|
|
562
|
+
test('Should handle references with Int8 id types', async () => {
|
|
563
|
+
const codegen = createSchemaCodeGen(`
|
|
564
|
+
interface Employee {
|
|
565
|
+
id: Int8!
|
|
566
|
+
name: String!
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
type Worker implements Employee @entity {
|
|
570
|
+
id: Int8!
|
|
571
|
+
name: String!
|
|
572
|
+
tasks: [Task!]
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
type Task @entity {
|
|
576
|
+
id: Int8!
|
|
577
|
+
employee: Employee!
|
|
578
|
+
workers: [Worker!] @derivedFrom(field: "tasks")
|
|
579
|
+
worker: Worker!
|
|
580
|
+
}
|
|
581
|
+
`);
|
|
582
|
+
const generatedTypes = codegen.generateTypes();
|
|
583
|
+
await testEntity(generatedTypes, {
|
|
584
|
+
name: 'Task',
|
|
585
|
+
members: [],
|
|
586
|
+
methods: [
|
|
587
|
+
{
|
|
588
|
+
name: 'constructor',
|
|
589
|
+
params: [new Param('id', new NamedType('Int8'))],
|
|
590
|
+
returnType: undefined,
|
|
591
|
+
body: "\n super()\n this.set('id', Value.fromI64(id))\n ",
|
|
592
|
+
},
|
|
593
|
+
{
|
|
594
|
+
name: 'save',
|
|
595
|
+
params: [],
|
|
596
|
+
returnType: new NamedType('void'),
|
|
597
|
+
body: '\n' +
|
|
598
|
+
" let id = this.get('id')\n" +
|
|
599
|
+
' assert(id != null,\n' +
|
|
600
|
+
" 'Cannot save Task entity without an ID')\n" +
|
|
601
|
+
' if (id) {\n' +
|
|
602
|
+
' assert(id.kind == ValueKind.INT8,\n' +
|
|
603
|
+
" `Entities of type Task must have an ID of type Int8 but the id '${id.displayData()}' is of type ${id.displayKind()}`)\n" +
|
|
604
|
+
" store.set('Task', id.toI64().toString(), this)\n" +
|
|
605
|
+
' }',
|
|
606
|
+
},
|
|
607
|
+
{
|
|
608
|
+
name: 'loadInBlock',
|
|
609
|
+
static: true,
|
|
610
|
+
params: [new Param('id', new NamedType('Int8'))],
|
|
611
|
+
returnType: new NullableType(new NamedType('Task')),
|
|
612
|
+
body: '\n' +
|
|
613
|
+
" return changetype<Task | null>(store.get_in_block('Task', id.toString()))\n" +
|
|
614
|
+
' ',
|
|
615
|
+
},
|
|
616
|
+
{
|
|
617
|
+
name: 'load',
|
|
618
|
+
static: true,
|
|
619
|
+
params: [new Param('id', new NamedType('Int8'))],
|
|
620
|
+
returnType: new NullableType(new NamedType('Task')),
|
|
621
|
+
body: '\n' +
|
|
622
|
+
" return changetype<Task | null>(store.get('Task', id.toString()))\n" +
|
|
623
|
+
' ',
|
|
624
|
+
},
|
|
625
|
+
{
|
|
626
|
+
name: 'get id',
|
|
627
|
+
params: [],
|
|
628
|
+
returnType: new NamedType('i64'),
|
|
629
|
+
body: `let value = this.get("id")
|
|
630
|
+
if (!value || value.kind == ValueKind.NULL) {
|
|
631
|
+
return 0;
|
|
632
|
+
} else {
|
|
633
|
+
return value.toI64()
|
|
634
|
+
}`,
|
|
635
|
+
},
|
|
636
|
+
{
|
|
637
|
+
name: 'set id',
|
|
638
|
+
params: [new Param('value', new NamedType('i64'))],
|
|
639
|
+
returnType: undefined,
|
|
640
|
+
body: "\n this.set('id', Value.fromI64(value))\n ",
|
|
641
|
+
},
|
|
642
|
+
{
|
|
643
|
+
name: 'get employee',
|
|
644
|
+
params: [],
|
|
645
|
+
returnType: new NamedType('i64'),
|
|
646
|
+
body: `let value = this.get('employee')
|
|
647
|
+
if (!value || value.kind == ValueKind.NULL) {
|
|
648
|
+
return 0;
|
|
649
|
+
} else {
|
|
650
|
+
return value.toI64()
|
|
651
|
+
}`,
|
|
652
|
+
},
|
|
653
|
+
{
|
|
654
|
+
name: 'set employee',
|
|
655
|
+
params: [new Param('value', new NamedType('i64'))],
|
|
656
|
+
returnType: undefined,
|
|
657
|
+
body: "\n this.set('employee', Value.fromI64(value))\n ",
|
|
658
|
+
},
|
|
659
|
+
{
|
|
660
|
+
name: 'get worker',
|
|
661
|
+
params: [],
|
|
662
|
+
returnType: new NamedType('i64'),
|
|
663
|
+
body: `let value = this.get('worker')
|
|
664
|
+
if (!value || value.kind == ValueKind.NULL) {
|
|
665
|
+
return 0;
|
|
666
|
+
} else {
|
|
667
|
+
return value.toI64()
|
|
668
|
+
}`,
|
|
669
|
+
},
|
|
670
|
+
{
|
|
671
|
+
name: 'set worker',
|
|
672
|
+
params: [new Param('value', new NamedType('i64'))],
|
|
673
|
+
returnType: undefined,
|
|
674
|
+
body: "\n this.set('worker', Value.fromI64(value))\n ",
|
|
675
|
+
},
|
|
676
|
+
{
|
|
677
|
+
name: 'get workers',
|
|
678
|
+
params: [],
|
|
679
|
+
returnType: new NamedType('WorkerLoader'),
|
|
680
|
+
body: "\n return new WorkerLoader('Task', this.get('id')!.toString(), 'workers')\n ",
|
|
681
|
+
},
|
|
682
|
+
],
|
|
683
|
+
});
|
|
684
|
+
});
|
|
562
685
|
test('get related method for WithBytes entity', async () => {
|
|
563
686
|
const codegen = createSchemaCodeGen(`
|
|
564
687
|
type WithBytes @entity {
|
|
@@ -124,10 +124,10 @@ export class ContractService {
|
|
|
124
124
|
}
|
|
125
125
|
try {
|
|
126
126
|
const result = await Promise.any(urls.map(url => this.fetchFromEtherscan(`${url}?module=contract&action=getsourcecode&address=${address}`).then(json => {
|
|
127
|
-
if (!json?.result
|
|
127
|
+
if (!json?.result) {
|
|
128
128
|
throw new Error(`No result: ${JSON.stringify(json)}`);
|
|
129
129
|
}
|
|
130
|
-
const { ContractName } = json.result[0];
|
|
130
|
+
const { ContractName } = json.result?.[0] ?? json.result ?? {};
|
|
131
131
|
if (!ContractName) {
|
|
132
132
|
throw new Error('Contract name is empty');
|
|
133
133
|
}
|
|
@@ -24,7 +24,7 @@ export const withSpinner = async (text, errorText, warningText, f) => {
|
|
|
24
24
|
const spinner = print.spin(text);
|
|
25
25
|
try {
|
|
26
26
|
const result = await f(spinner);
|
|
27
|
-
if (typeof result === 'object') {
|
|
27
|
+
if (result && typeof result === 'object') {
|
|
28
28
|
const hasError = Object.keys(result).includes('error');
|
|
29
29
|
const hasWarning = Object.keys(result).includes('warning');
|
|
30
30
|
const hasResult = Object.keys(result).includes('result');
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import { formatContractName, formatSubgraphName, getSubgraphBasename } from './subgraph';
|
|
3
|
+
describe('getSubgraphBasename', () => {
|
|
4
|
+
it('returns the last segment of a subgraph name', () => {
|
|
5
|
+
expect(getSubgraphBasename('user/my-subgraph')).toBe('my-subgraph');
|
|
6
|
+
expect(getSubgraphBasename('org/project')).toBe('project');
|
|
7
|
+
});
|
|
8
|
+
it('returns the full name if no slash is present', () => {
|
|
9
|
+
expect(getSubgraphBasename('single-name')).toBe('single-name');
|
|
10
|
+
});
|
|
11
|
+
});
|
|
12
|
+
describe('formatSubgraphName', () => {
|
|
13
|
+
it('converts to lowercase', () => {
|
|
14
|
+
expect(formatSubgraphName('MySubGraph')).toBe('mysubgraph');
|
|
15
|
+
});
|
|
16
|
+
it('replaces spaces with hyphens', () => {
|
|
17
|
+
expect(formatSubgraphName('my subgraph name')).toBe('my-subgraph-name');
|
|
18
|
+
expect(formatSubgraphName('multiple spaces')).toBe('multiple-spaces');
|
|
19
|
+
});
|
|
20
|
+
it('removes special characters', () => {
|
|
21
|
+
expect(formatSubgraphName('my$special@subgraph!')).toBe('myspecialsubgraph');
|
|
22
|
+
});
|
|
23
|
+
it('keeps alphanumeric characters, hyphens and underscores', () => {
|
|
24
|
+
expect(formatSubgraphName('my-subgraph_123')).toBe('my-subgraph_123');
|
|
25
|
+
});
|
|
26
|
+
});
|
|
27
|
+
describe('formatContractName', () => {
|
|
28
|
+
it('replaces spaces and dots with underscores', () => {
|
|
29
|
+
expect(formatContractName('My Contract')).toBe('My_Contract');
|
|
30
|
+
expect(formatContractName('contract.name')).toBe('contract_name');
|
|
31
|
+
expect(formatContractName('multiple...dots')).toBe('multiple_dots');
|
|
32
|
+
});
|
|
33
|
+
it('removes special characters but keeps alphanumeric, hyphens and underscores', () => {
|
|
34
|
+
expect(formatContractName('Contract$$$Name')).toBe('ContractName');
|
|
35
|
+
expect(formatContractName('My-Contract_123')).toBe('My-Contract_123');
|
|
36
|
+
expect(formatContractName('My Contract $$$$')).toBe('My_Contract_');
|
|
37
|
+
});
|
|
38
|
+
it('preserves case', () => {
|
|
39
|
+
expect(formatContractName('MyContractName')).toBe('MyContractName');
|
|
40
|
+
});
|
|
41
|
+
});
|
package/dist/commands/init.js
CHANGED
|
@@ -15,7 +15,7 @@ import { retryWithPrompt } from '../command-helpers/retry.js';
|
|
|
15
15
|
import { generateScaffold, writeScaffold } from '../command-helpers/scaffold.js';
|
|
16
16
|
import { sortWithPriority } from '../command-helpers/sort.js';
|
|
17
17
|
import { withSpinner } from '../command-helpers/spinner.js';
|
|
18
|
-
import { formatSubgraphName, getSubgraphBasename } from '../command-helpers/subgraph.js';
|
|
18
|
+
import { formatContractName, formatSubgraphName, getSubgraphBasename, } from '../command-helpers/subgraph.js';
|
|
19
19
|
import { GRAPH_CLI_SHARED_HEADERS } from '../constants.js';
|
|
20
20
|
import debugFactory from '../debug.js';
|
|
21
21
|
import EthereumABI from '../protocols/ethereum/abi.js';
|
|
@@ -215,7 +215,7 @@ export default class InitCommand extends Command {
|
|
|
215
215
|
indexEvents,
|
|
216
216
|
network,
|
|
217
217
|
subgraphName,
|
|
218
|
-
contractName
|
|
218
|
+
contractName,
|
|
219
219
|
node,
|
|
220
220
|
startBlock,
|
|
221
221
|
spkgPath,
|
|
@@ -268,7 +268,7 @@ export default class InitCommand extends Command {
|
|
|
268
268
|
network: answers.network,
|
|
269
269
|
source: answers.source,
|
|
270
270
|
indexEvents: answers.indexEvents,
|
|
271
|
-
contractName: answers.contractName
|
|
271
|
+
contractName: answers.contractName,
|
|
272
272
|
node,
|
|
273
273
|
startBlock: answers.startBlock,
|
|
274
274
|
spkgPath: answers.spkgPath,
|
|
@@ -537,29 +537,31 @@ async function processInitForm({ abi: initAbi, abiPath: initAbiPath, directory:
|
|
|
537
537
|
source = address;
|
|
538
538
|
return address;
|
|
539
539
|
}
|
|
540
|
-
|
|
541
|
-
if (sourcifyContractInfo) {
|
|
542
|
-
initStartBlock ??= sourcifyContractInfo.startBlock;
|
|
543
|
-
initContractName ??= sourcifyContractInfo.name;
|
|
544
|
-
initAbi ??= sourcifyContractInfo.abi;
|
|
545
|
-
initDebugger.extend('processInitForm')("infoFromSourcify: '%s'/'%s'", initStartBlock, initContractName);
|
|
546
|
-
}
|
|
547
|
-
// If ABI is not provided, try to fetch it from Etherscan API
|
|
540
|
+
// If ABI is not provided, try to fetch it from Sourcify/Etherscan API
|
|
548
541
|
if (protocolInstance.hasABIs() && !initAbi) {
|
|
549
|
-
|
|
550
|
-
|
|
542
|
+
const sourcifyContractInfo = await withSpinner('Fetching ABI from Sourcify API...', 'Failed to fetch ABI', 'Warning fetching ABI', () => contractService.getFromSourcify(protocolInstance.getABI(), network.id, address));
|
|
543
|
+
if (sourcifyContractInfo) {
|
|
544
|
+
initStartBlock ??= sourcifyContractInfo.startBlock;
|
|
545
|
+
initContractName ??= sourcifyContractInfo.name;
|
|
546
|
+
abiFromApi ??= sourcifyContractInfo.abi;
|
|
547
|
+
initDebugger.extend('processInitForm')("infoFromSourcify: '%s'/'%s'", initStartBlock, initContractName);
|
|
548
|
+
}
|
|
549
|
+
else {
|
|
550
|
+
abiFromApi = await retryWithPrompt(() => withSpinner('Fetching ABI from Contract API...', 'Failed to fetch ABI', 'Warning fetching ABI', () => contractService.getABI(protocolInstance.getABI(), network.id, address)));
|
|
551
|
+
initDebugger.extend('processInitForm')("abiFromEtherscan ABI: '%s'", abiFromApi?.name);
|
|
552
|
+
}
|
|
551
553
|
}
|
|
552
554
|
else {
|
|
553
555
|
abiFromApi = initAbi;
|
|
554
556
|
}
|
|
555
557
|
// If startBlock is not provided, try to fetch it from Etherscan API
|
|
556
558
|
if (!initStartBlock) {
|
|
557
|
-
startBlock = await retryWithPrompt(() => withSpinner('Fetching start block from
|
|
559
|
+
startBlock = await retryWithPrompt(() => withSpinner('Fetching start block from Contract API...', 'Failed to fetch start block', 'Warning fetching start block', () => contractService.getStartBlock(network.id, address)));
|
|
558
560
|
initDebugger.extend('processInitForm')("startBlockFromEtherscan: '%s'", startBlock);
|
|
559
561
|
}
|
|
560
562
|
// If contract name is not provided, try to fetch it from Etherscan API
|
|
561
563
|
if (!initContractName) {
|
|
562
|
-
contractName = await retryWithPrompt(() => withSpinner('Fetching contract name from
|
|
564
|
+
contractName = await retryWithPrompt(() => withSpinner('Fetching contract name from Contract API...', 'Failed to fetch contract name', 'Warning fetching contract name', () => contractService.getContractName(network.id, address)));
|
|
563
565
|
initDebugger.extend('processInitForm')("contractNameFromEtherscan: '%s'", contractName);
|
|
564
566
|
}
|
|
565
567
|
source = address;
|
|
@@ -640,7 +642,7 @@ async function processInitForm({ abi: initAbi, abiPath: initAbiPath, directory:
|
|
|
640
642
|
type: 'input',
|
|
641
643
|
name: 'startBlock',
|
|
642
644
|
message: 'Start block',
|
|
643
|
-
initial: () => initStartBlock || startBlock ||
|
|
645
|
+
initial: () => String(initStartBlock || startBlock || 0),
|
|
644
646
|
skip: () => initFromExample !== undefined || isSubstreams,
|
|
645
647
|
validate: value => initFromExample !== undefined ||
|
|
646
648
|
isSubstreams ||
|
|
@@ -656,7 +658,7 @@ async function processInitForm({ abi: initAbi, abiPath: initAbiPath, directory:
|
|
|
656
658
|
type: 'input',
|
|
657
659
|
name: 'contractName',
|
|
658
660
|
message: 'Contract name',
|
|
659
|
-
initial: () => initContractName || contractName ||
|
|
661
|
+
initial: () => initContractName || contractName || DEFAULT_CONTRACT_NAME,
|
|
660
662
|
skip: () => initFromExample !== undefined || !protocolInstance.hasContract() || isSubstreams,
|
|
661
663
|
validate: value => initFromExample !== undefined ||
|
|
662
664
|
!protocolInstance.hasContract() ||
|
|
@@ -930,7 +932,7 @@ async function initSubgraphFromContract({ protocolInstance, subgraphName, direct
|
|
|
930
932
|
network,
|
|
931
933
|
source,
|
|
932
934
|
indexEvents,
|
|
933
|
-
contractName,
|
|
935
|
+
contractName: formatContractName(contractName || DEFAULT_CONTRACT_NAME),
|
|
934
936
|
startBlock,
|
|
935
937
|
node,
|
|
936
938
|
spkgPath,
|
package/dist/scaffold/mapping.js
CHANGED
|
@@ -9,10 +9,11 @@ export const VALUE_TYPECAST_MAP = {
|
|
|
9
9
|
export const generateFieldAssignment = (key, value, type) => {
|
|
10
10
|
const safeKey = key.map(k => util.handleReservedWord(k));
|
|
11
11
|
const safeValue = value.map(v => util.handleReservedWord(v));
|
|
12
|
+
const cleanType = type.replace(/\[\d+\]/g, '[]');
|
|
12
13
|
let rightSide = `event.params.${safeValue.join('.')}`;
|
|
13
14
|
const imports = [];
|
|
14
|
-
if (
|
|
15
|
-
const castTo = VALUE_TYPECAST_MAP[
|
|
15
|
+
if (cleanType in VALUE_TYPECAST_MAP) {
|
|
16
|
+
const castTo = VALUE_TYPECAST_MAP[cleanType];
|
|
16
17
|
rightSide = `changetype<${castTo}>(${rightSide})`;
|
|
17
18
|
imports.push(castTo.replace('[]', ''));
|
|
18
19
|
}
|
package/dist/scaffold/schema.js
CHANGED
|
@@ -57,7 +57,10 @@ export const generateExampleEntityType = (protocol, events) => {
|
|
|
57
57
|
id: Bytes!
|
|
58
58
|
count: BigInt!
|
|
59
59
|
${events[0].inputs
|
|
60
|
-
.reduce((acc, input, index) =>
|
|
60
|
+
.reduce((acc, input, index) => {
|
|
61
|
+
input.name = renameNameIfNeeded(input.name);
|
|
62
|
+
return acc.concat(generateEventFields({ input, index, protocolName: protocol.name }));
|
|
63
|
+
}, [])
|
|
61
64
|
.slice(0, 2)
|
|
62
65
|
.join('\n')}
|
|
63
66
|
}`;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"root":["../src/constants.ts","../src/debug.ts","../src/fetch.ts","../src/index.ts","../src/migrations.ts","../src/schema.ts","../src/subgraph.ts","../src/type-generator.ts","../src/utils.ts","../src/version.ts","../src/watcher.ts","../src/codegen/schema.test.ts","../src/codegen/schema.ts","../src/codegen/template.ts","../src/codegen/typescript.ts","../src/codegen/util.test.ts","../src/codegen/util.ts","../src/codegen/types/conversions.ts","../src/codegen/types/index.test.ts","../src/codegen/types/index.ts","../src/command-helpers/auth.ts","../src/command-helpers/compiler.test.ts","../src/command-helpers/compiler.ts","../src/command-helpers/contracts.test.ts","../src/command-helpers/contracts.ts","../src/command-helpers/data-sources.ts","../src/command-helpers/file-resolver.test.ts","../src/command-helpers/file-resolver.ts","../src/command-helpers/fs.ts","../src/command-helpers/ipfs.ts","../src/command-helpers/jsonrpc.ts","../src/command-helpers/network.test.ts","../src/command-helpers/network.ts","../src/command-helpers/node.ts","../src/command-helpers/prompt-manager.ts","../src/command-helpers/registry.ts","../src/command-helpers/retry.ts","../src/command-helpers/scaffold.ts","../src/command-helpers/sort.test.ts","../src/command-helpers/sort.ts","../src/command-helpers/spinner.ts","../src/command-helpers/subgraph.ts","../src/command-helpers/version.test.ts","../src/command-helpers/version.ts","../src/commands/add.ts","../src/commands/auth.ts","../src/commands/build.ts","../src/commands/clean.ts","../src/commands/codegen.ts","../src/commands/create.ts","../src/commands/deploy.ts","../src/commands/init.ts","../src/commands/local.ts","../src/commands/publish.ts","../src/commands/remove.ts","../src/commands/test.ts","../src/compiler/asc.ts","../src/compiler/index.ts","../src/migrations/mapping_api_version_0_0_1.ts","../src/migrations/mapping_api_version_0_0_2.ts","../src/migrations/mapping_api_version_0_0_3.ts","../src/migrations/mapping_api_version_0_0_4.ts","../src/migrations/mapping_api_version_0_0_5.ts","../src/migrations/spec_version_0_0_2.ts","../src/migrations/spec_version_0_0_3.ts","../src/migrations/util/load-manifest.ts","../src/migrations/util/versions.ts","../src/protocols/contract.ts","../src/protocols/file_template.ts","../src/protocols/index.ts","../src/protocols/subgraph.ts","../src/protocols/arweave/subgraph.ts","../src/protocols/arweave/scaffold/manifest.ts","../src/protocols/arweave/scaffold/mapping.ts","../src/protocols/cosmos/subgraph.ts","../src/protocols/cosmos/scaffold/manifest.ts","../src/protocols/cosmos/scaffold/mapping.ts","../src/protocols/ethereum/abi.ts","../src/protocols/ethereum/contract.ts","../src/protocols/ethereum/subgraph.ts","../src/protocols/ethereum/type-generator.ts","../src/protocols/ethereum/codegen/abi.test.ts","../src/protocols/ethereum/codegen/abi.ts","../src/protocols/ethereum/codegen/template.ts","../src/protocols/ethereum/scaffold/manifest.ts","../src/protocols/ethereum/scaffold/mapping.ts","../src/protocols/near/contract.ts","../src/protocols/near/subgraph.ts","../src/protocols/near/scaffold/manifest.ts","../src/protocols/near/scaffold/mapping.ts","../src/protocols/subgraph/subgraph.ts","../src/protocols/subgraph/scaffold/manifest.ts","../src/protocols/subgraph/scaffold/mapping.ts","../src/protocols/substreams/subgraph.ts","../src/protocols/substreams/scaffold/manifest.ts","../src/scaffold/cosmos.test.ts","../src/scaffold/ethereum.test.ts","../src/scaffold/get-docker-file.ts","../src/scaffold/get-git-ignore.ts","../src/scaffold/index.ts","../src/scaffold/mapping.ts","../src/scaffold/near.test.ts","../src/scaffold/schema.ts","../src/scaffold/tests.ts","../src/validation/contract.ts","../src/validation/index.ts","../src/validation/manifest.ts","../src/validation/schema.test.ts","../src/validation/schema.ts"],"version":"5.7.3"}
|
|
1
|
+
{"root":["../src/constants.ts","../src/debug.ts","../src/fetch.ts","../src/index.ts","../src/migrations.ts","../src/schema.ts","../src/subgraph.ts","../src/type-generator.ts","../src/utils.ts","../src/version.ts","../src/watcher.ts","../src/codegen/schema.test.ts","../src/codegen/schema.ts","../src/codegen/template.ts","../src/codegen/typescript.ts","../src/codegen/util.test.ts","../src/codegen/util.ts","../src/codegen/types/conversions.ts","../src/codegen/types/index.test.ts","../src/codegen/types/index.ts","../src/command-helpers/auth.ts","../src/command-helpers/compiler.test.ts","../src/command-helpers/compiler.ts","../src/command-helpers/contracts.test.ts","../src/command-helpers/contracts.ts","../src/command-helpers/data-sources.ts","../src/command-helpers/file-resolver.test.ts","../src/command-helpers/file-resolver.ts","../src/command-helpers/fs.ts","../src/command-helpers/ipfs.ts","../src/command-helpers/jsonrpc.ts","../src/command-helpers/network.test.ts","../src/command-helpers/network.ts","../src/command-helpers/node.ts","../src/command-helpers/prompt-manager.ts","../src/command-helpers/registry.ts","../src/command-helpers/retry.ts","../src/command-helpers/scaffold.ts","../src/command-helpers/sort.test.ts","../src/command-helpers/sort.ts","../src/command-helpers/spinner.ts","../src/command-helpers/subgraph.test.ts","../src/command-helpers/subgraph.ts","../src/command-helpers/version.test.ts","../src/command-helpers/version.ts","../src/commands/add.ts","../src/commands/auth.ts","../src/commands/build.ts","../src/commands/clean.ts","../src/commands/codegen.ts","../src/commands/create.ts","../src/commands/deploy.ts","../src/commands/init.ts","../src/commands/local.ts","../src/commands/publish.ts","../src/commands/remove.ts","../src/commands/test.ts","../src/compiler/asc.ts","../src/compiler/index.ts","../src/migrations/mapping_api_version_0_0_1.ts","../src/migrations/mapping_api_version_0_0_2.ts","../src/migrations/mapping_api_version_0_0_3.ts","../src/migrations/mapping_api_version_0_0_4.ts","../src/migrations/mapping_api_version_0_0_5.ts","../src/migrations/spec_version_0_0_2.ts","../src/migrations/spec_version_0_0_3.ts","../src/migrations/util/load-manifest.ts","../src/migrations/util/versions.ts","../src/protocols/contract.ts","../src/protocols/file_template.ts","../src/protocols/index.ts","../src/protocols/subgraph.ts","../src/protocols/arweave/subgraph.ts","../src/protocols/arweave/scaffold/manifest.ts","../src/protocols/arweave/scaffold/mapping.ts","../src/protocols/cosmos/subgraph.ts","../src/protocols/cosmos/scaffold/manifest.ts","../src/protocols/cosmos/scaffold/mapping.ts","../src/protocols/ethereum/abi.ts","../src/protocols/ethereum/contract.ts","../src/protocols/ethereum/subgraph.ts","../src/protocols/ethereum/type-generator.ts","../src/protocols/ethereum/codegen/abi.test.ts","../src/protocols/ethereum/codegen/abi.ts","../src/protocols/ethereum/codegen/template.ts","../src/protocols/ethereum/scaffold/manifest.ts","../src/protocols/ethereum/scaffold/mapping.ts","../src/protocols/near/contract.ts","../src/protocols/near/subgraph.ts","../src/protocols/near/scaffold/manifest.ts","../src/protocols/near/scaffold/mapping.ts","../src/protocols/subgraph/subgraph.ts","../src/protocols/subgraph/scaffold/manifest.ts","../src/protocols/subgraph/scaffold/mapping.ts","../src/protocols/substreams/subgraph.ts","../src/protocols/substreams/scaffold/manifest.ts","../src/scaffold/cosmos.test.ts","../src/scaffold/ethereum.test.ts","../src/scaffold/get-docker-file.ts","../src/scaffold/get-git-ignore.ts","../src/scaffold/index.ts","../src/scaffold/mapping.ts","../src/scaffold/near.test.ts","../src/scaffold/schema.ts","../src/scaffold/tests.ts","../src/validation/contract.ts","../src/validation/index.ts","../src/validation/manifest.ts","../src/validation/schema.test.ts","../src/validation/schema.ts"],"version":"5.7.3"}
|
package/oclif.manifest.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@graphprotocol/graph-cli",
|
|
3
|
-
"version": "0.96.
|
|
3
|
+
"version": "0.96.1-alpha-20250227201537-7fda6f366205e455e0af20f7f8499fc4f6938f96",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "CLI for building for and deploying to The Graph",
|
|
6
6
|
"repository": {
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
],
|
|
28
28
|
"dependencies": {
|
|
29
29
|
"@float-capital/float-subgraph-uncrashable": "0.0.0-internal-testing.5",
|
|
30
|
-
"@oclif/core": "4.2.
|
|
30
|
+
"@oclif/core": "4.2.8",
|
|
31
31
|
"@oclif/plugin-autocomplete": "^3.2.11",
|
|
32
32
|
"@oclif/plugin-not-found": "^3.2.29",
|
|
33
33
|
"@oclif/plugin-warn-if-update-available": "^3.1.24",
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
"assemblyscript": "0.19.23",
|
|
37
37
|
"chokidar": "4.0.3",
|
|
38
38
|
"debug": "4.4.0",
|
|
39
|
-
"docker-compose": "1.1.
|
|
39
|
+
"docker-compose": "1.1.1",
|
|
40
40
|
"fs-extra": "11.3.0",
|
|
41
41
|
"glob": "11.0.1",
|
|
42
42
|
"gluegun": "5.2.0",
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
"js-yaml": "4.1.0",
|
|
47
47
|
"kubo-rpc-client": "^5.0.2",
|
|
48
48
|
"open": "10.1.0",
|
|
49
|
-
"prettier": "3.
|
|
49
|
+
"prettier": "3.5.2",
|
|
50
50
|
"semver": "7.7.1",
|
|
51
51
|
"tmp-promise": "3.0.3",
|
|
52
52
|
"undici": "7.3.0",
|