@show-karma/karma-gap-sdk 0.3.4 → 0.3.5
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/core/abi/CommunityResolverABI.json +508 -0
- package/core/class/AttestationIPFS.d.ts +7 -0
- package/core/class/AttestationIPFS.js +10 -0
- package/core/class/GAP.d.ts +7 -0
- package/core/class/GAP.js +14 -0
- package/core/class/GraphQL/Fetcher.d.ts +132 -0
- package/core/class/GraphQL/Fetcher.js +7 -0
- package/core/class/GraphQL/GAPFetcher.d.ts +160 -0
- package/core/class/GraphQL/GAPFetcher.js +516 -0
- package/core/class/IPFS/IPFS.d.ts +13 -0
- package/core/class/IPFS/IPFS.js +24 -0
- package/core/class/contract/MultiAttest.d.ts +10 -0
- package/core/class/contract/MultiAttest.js +19 -0
- package/core/consts.js +4 -34
- package/core/types.d.ts +1 -0
- package/package.json +1 -1
- package/readme.md +34 -39
- package/config/keys.example.json +0 -6
- package/core/abi/EAS.json +0 -1
- package/core/abi/SchemaRegistry.json +0 -1
- package/core/class/Attestation.ts +0 -402
- package/core/class/Fetcher.ts +0 -202
- package/core/class/GAP.ts +0 -398
- package/core/class/GapSchema.ts +0 -90
- package/core/class/Gelato/Gelato.ts +0 -286
- package/core/class/GraphQL/AxiosGQL.ts +0 -29
- package/core/class/GraphQL/EASClient.ts +0 -34
- package/core/class/GraphQL/GapEasClient.ts +0 -845
- package/core/class/GraphQL/index.ts +0 -3
- package/core/class/Schema.ts +0 -609
- package/core/class/SchemaError.ts +0 -36
- package/core/class/contract/GapContract.ts +0 -353
- package/core/class/entities/Community.ts +0 -115
- package/core/class/entities/Grant.ts +0 -309
- package/core/class/entities/MemberOf.ts +0 -42
- package/core/class/entities/Milestone.ts +0 -269
- package/core/class/entities/Project.ts +0 -370
- package/core/class/entities/index.ts +0 -5
- package/core/class/index.ts +0 -10
- package/core/class/karma-indexer/GapIndexerClient.ts +0 -245
- package/core/class/remote-storage/IpfsStorage.ts +0 -51
- package/core/class/remote-storage/RemoteStorage.ts +0 -65
- package/core/class/types/attestations.ts +0 -158
- package/core/consts.ts +0 -282
- package/core/index.ts +0 -7
- package/core/scripts/deploy.ts +0 -67
- package/core/scripts/index.ts +0 -1
- package/core/types.ts +0 -186
- package/core/utils/gelato/index.ts +0 -3
- package/core/utils/gelato/send-gelato-txn.ts +0 -114
- package/core/utils/gelato/sponsor-handler.ts +0 -77
- package/core/utils/gelato/watch-gelato-txn.ts +0 -67
- package/core/utils/get-date.ts +0 -3
- package/core/utils/get-ipfs-data.ts +0 -13
- package/core/utils/get-web3-provider.ts +0 -20
- package/core/utils/gql-queries.ts +0 -133
- package/core/utils/index.ts +0 -7
- package/core/utils/map-filter.ts +0 -21
- package/core/utils/serialize-bigint.ts +0 -7
- package/core/utils/to-unix.ts +0 -18
- package/csv-upload/.gitkeep +0 -0
- package/csv-upload/example.csv +0 -2
- package/csv-upload/scripts/run.ts +0 -193
- package/docs/.gitkeep +0 -0
- package/docs/images/attestation-architecture.png +0 -0
- package/docs/images/dfd-get-projects.png +0 -0
- package/index.ts +0 -1
- package/schemas/.gitkeep +0 -0
- package/schemas/GAP-schemas-1692135812877.json +0 -33
- package/test-file.ts +0 -92
- package/tsconfig.json +0 -26
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { NFTStorage } from "nft.storage";
|
|
2
|
+
export declare abstract class IPFS {
|
|
3
|
+
protected client: NFTStorage;
|
|
4
|
+
constructor(ipfsKey: string);
|
|
5
|
+
/**
|
|
6
|
+
* Insert the data in the IPFS and return the cid.
|
|
7
|
+
*/
|
|
8
|
+
save<T = unknown>(data: T): Promise<string>;
|
|
9
|
+
/**
|
|
10
|
+
* Encode Attestation data using IPFS cid
|
|
11
|
+
*/
|
|
12
|
+
protected abstract encode(data: string, storageType: number): any;
|
|
13
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.IPFS = void 0;
|
|
4
|
+
const nft_storage_1 = require("nft.storage");
|
|
5
|
+
const SchemaError_1 = require("../SchemaError");
|
|
6
|
+
class IPFS {
|
|
7
|
+
constructor(ipfsKey) {
|
|
8
|
+
this.client = new nft_storage_1.NFTStorage({ token: ipfsKey });
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Insert the data in the IPFS and return the cid.
|
|
12
|
+
*/
|
|
13
|
+
async save(data) {
|
|
14
|
+
try {
|
|
15
|
+
const blob = new nft_storage_1.Blob([JSON.stringify(data)], { type: 'application/json' });
|
|
16
|
+
const cid = await this.client.storeBlob(blob);
|
|
17
|
+
return cid;
|
|
18
|
+
}
|
|
19
|
+
catch (error) {
|
|
20
|
+
throw new SchemaError_1.AttestationError('IPFS_UPLOAD', `Error adding data to IPFS`);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
exports.IPFS = IPFS;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { SignerOrProvider } from "@ethereum-attestation-service/eas-sdk/dist/transaction";
|
|
2
|
+
import { Hex, MultiAttestData } from "core/types";
|
|
3
|
+
export declare class MultiAttest {
|
|
4
|
+
/**
|
|
5
|
+
* Performs a referenced multi attestation.
|
|
6
|
+
*
|
|
7
|
+
* @returns an array with the attestation UIDs.
|
|
8
|
+
*/
|
|
9
|
+
static send(signer: SignerOrProvider, payload: MultiAttestData[]): Promise<Hex[]>;
|
|
10
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MultiAttest = void 0;
|
|
4
|
+
const GAP_1 = require("../GAP");
|
|
5
|
+
class MultiAttest {
|
|
6
|
+
/**
|
|
7
|
+
* Performs a referenced multi attestation.
|
|
8
|
+
*
|
|
9
|
+
* @returns an array with the attestation UIDs.
|
|
10
|
+
*/
|
|
11
|
+
static async send(signer, payload) {
|
|
12
|
+
const contract = GAP_1.GAP.getMulticall(signer);
|
|
13
|
+
const tx = await contract.functions.multiSequentialAttest(payload);
|
|
14
|
+
const result = await tx.wait?.();
|
|
15
|
+
const attestations = result.logs?.map((m) => m.data);
|
|
16
|
+
return attestations;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
exports.MultiAttest = MultiAttest;
|
package/core/consts.js
CHANGED
|
@@ -20,40 +20,6 @@ exports.zeroAddress = exports.nullResolver;
|
|
|
20
20
|
* The networks that are supported by the EAS
|
|
21
21
|
*/
|
|
22
22
|
exports.Networks = {
|
|
23
|
-
// mainnet: {
|
|
24
|
-
// url: "https://easscan.org/graphql",
|
|
25
|
-
// chainId: 1,
|
|
26
|
-
// contracts: {
|
|
27
|
-
// eas: "0xA1207F3BBa224E2c9c3c6D5aF63D0eb1582Ce587",
|
|
28
|
-
// schema: "0xA7b39296258348C78294F95B872b282326A97BDF",
|
|
29
|
-
// multicall:''
|
|
30
|
-
// },
|
|
31
|
-
// schemas: {
|
|
32
|
-
// Grant: "",
|
|
33
|
-
// GrantVerified: "",
|
|
34
|
-
// MemberOf: "",
|
|
35
|
-
// MilestoneApproved: "",
|
|
36
|
-
// MilestoneCompleted: "",
|
|
37
|
-
// Project: "",
|
|
38
|
-
// },
|
|
39
|
-
// },
|
|
40
|
-
// "base-goerli": {
|
|
41
|
-
// chainId: 5,
|
|
42
|
-
// url: "https://base-goerli.easscan.org/graphql",
|
|
43
|
-
// contracts: {
|
|
44
|
-
// eas: "0xAcfE09Fd03f7812F022FBf636700AdEA18Fd2A7A",
|
|
45
|
-
// schema: "0x720c2bA66D19A725143FBf5fDC5b4ADA2742682E",
|
|
46
|
-
// multicall:''
|
|
47
|
-
// },
|
|
48
|
-
// schemas: {
|
|
49
|
-
// Grant: "",
|
|
50
|
-
// GrantVerified: "",
|
|
51
|
-
// MemberOf: "",
|
|
52
|
-
// MilestoneApproved: "",
|
|
53
|
-
// MilestoneCompleted: "",
|
|
54
|
-
// Project: "",
|
|
55
|
-
// },
|
|
56
|
-
// },
|
|
57
23
|
optimism: {
|
|
58
24
|
chainId: 10,
|
|
59
25
|
url: 'https://optimism.easscan.org/graphql',
|
|
@@ -63,6 +29,7 @@ exports.Networks = {
|
|
|
63
29
|
schema: '0x4200000000000000000000000000000000000020',
|
|
64
30
|
multicall: '0xd2eD366393FDfd243931Fe48e9fb65A192B0018c',
|
|
65
31
|
projectResolver: '0x7177AdC0f924b695C0294A40C4C5FEFf5EE1E141',
|
|
32
|
+
communityResolver: '0x6dC1D6b864e8BEf815806f9e4677123496e12026',
|
|
66
33
|
},
|
|
67
34
|
schemas: {
|
|
68
35
|
Community: '0x721c17b065dccc5c916e0c2708d0ef50f1810591b76d0402ff6fe5accbd8488f',
|
|
@@ -84,6 +51,7 @@ exports.Networks = {
|
|
|
84
51
|
schema: '0x4200000000000000000000000000000000000020',
|
|
85
52
|
multicall: '0x5D5a8032b2FA06652804c33F60DcEA00e389B732',
|
|
86
53
|
projectResolver: '0xbCf8910Bc3971eA59D93256357b76E846CF2e1F8',
|
|
54
|
+
communityResolver: '0xa09369bDE7E4403a9C821AffA00E649cF85Ef09e',
|
|
87
55
|
},
|
|
88
56
|
schemas: {
|
|
89
57
|
Community: '0xc1aade58410b3fd807c19845181996721248459c5f042284f27d21cec12a38d1',
|
|
@@ -106,6 +74,7 @@ exports.Networks = {
|
|
|
106
74
|
schema: '0xA310da9c5B885E7fb3fbA9D66E9Ba6Df512b78eB',
|
|
107
75
|
multicall: '0x6dC1D6b864e8BEf815806f9e4677123496e12026',
|
|
108
76
|
projectResolver: '0x28BE0b0515be8BB8822aF1467A6613795E74717b',
|
|
77
|
+
communityResolver: '0xD534C4704F82494aBbc901560046fB62Ac63E9C4',
|
|
109
78
|
},
|
|
110
79
|
schemas: {
|
|
111
80
|
Community: '0xc604f0661cfd522583835ed2b2c644b80e068139d287f93c7f1680888894bacc',
|
|
@@ -127,6 +96,7 @@ exports.Networks = {
|
|
|
127
96
|
schema: '0x0a7E2Ff54e76B8E6659aedc9103FB21c038050D0',
|
|
128
97
|
multicall: '0xec8d7BFe344790FD860920C41B46B259c005727A',
|
|
129
98
|
projectResolver: '0x099787D5a5aC92779A519CfD925ACB0Dc7E8bd23',
|
|
99
|
+
communityResolver: '0xa9E55D9F52d7B47792d2Db15F6A9674c56ccc5C9',
|
|
130
100
|
},
|
|
131
101
|
schemas: {
|
|
132
102
|
Community: '0xf3d790c7fdab6c1b1f25ffcc9289e5be2792eb596d2851a4d059c8aae1bc8b2e',
|
package/core/types.d.ts
CHANGED
package/package.json
CHANGED
package/readme.md
CHANGED
|
@@ -5,20 +5,25 @@
|
|
|
5
5
|
1. [What is GAP SDK?](#1-what-is-gap-sdk)
|
|
6
6
|
2. [Architecture](#2-architecture)
|
|
7
7
|
3. [Getting started](#3-getting-started)
|
|
8
|
-
4. [
|
|
9
|
-
5. [
|
|
10
|
-
6. [
|
|
8
|
+
4. [Getting attestations](#4-getting-attestations)
|
|
9
|
+
5. [Attesting data in a Frontend](#5-attesting-data-in-a-frontend)
|
|
10
|
+
6. [Attesting data in a Backend](#6-attesting-data-in-a-backend)
|
|
11
11
|
7. [Gasless transactions with Gelato](#7-gasless-transactions-with-gelato)
|
|
12
12
|
8. [Speed up requests with a Custom API](#8-custom-api)
|
|
13
13
|
|
|
14
14
|
## 1. What is GAP SDK?
|
|
15
15
|
|
|
16
|
-
The GAP SDK is a
|
|
16
|
+
The GAP SDK is a tool that provides ease of use when working with the [accountability protocol](https://gap.karmahq.xyz). Its core is developed to support customization\* and flexibility.
|
|
17
17
|
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
Through this tool, you will be able to:
|
|
19
|
+
|
|
20
|
+
- Get and display Communities, Projects, Members, Grants, Milestones, and all of their dependencies.
|
|
21
|
+
- Perform attestations for all of the above.
|
|
22
|
+
- Execute revocations for all of the above.
|
|
20
23
|
- Utilize gasless transactions with [Gelato Relay](https://relay.gelato.network).
|
|
21
|
-
-
|
|
24
|
+
- Harness a custom API to expedite requests, as it adheres to the defined parameters.
|
|
25
|
+
|
|
26
|
+
> \* We are currently working on enhancing the ability to customize this API through tools that facilitate the modification of parameters. This feature may appear confusing if you attempt to modify certain parameters, such as default schemas and contracts, at the moment.
|
|
22
27
|
|
|
23
28
|
## 2. Architecture
|
|
24
29
|
|
|
@@ -40,13 +45,13 @@ Here's an example of how all these modules work together when retrieving Project
|
|
|
40
45
|
|
|
41
46
|

|
|
42
47
|
|
|
43
|
-
In this diagram, you can already discern the benefits of using a Custom API to obtain data from the network and construct your own indexer, as opposed to relying on EAS's GraphQL API. We will delve into this further in [
|
|
48
|
+
In this diagram, you can already discern the benefits of using a Custom API to obtain data from the network and construct your own indexer, as opposed to relying on EAS's GraphQL API. We will delve into this further in [Chapter 8](#8-custom-api).
|
|
44
49
|
|
|
45
50
|
> **Note**: GAP currently does not fully support multichain, and creating more than one instance can result in unexpected errors when using the fetcher. This feature is currently under development.
|
|
46
51
|
|
|
47
52
|
### Attestations
|
|
48
53
|
|
|
49
|
-
|
|
54
|
+
Attestations are categorized into various types of entities to establish a relationship between them and enable users to modify their attestation details without losing references to the main attestation. As a result, entities like community, project, grant, and members require two attestations: the first defines the entity, and the second defines its details. Due to this structure, all these entities will include a `details` property that contains all the data inserted into that attestation. For example:
|
|
50
55
|
|
|
51
56
|
```ts
|
|
52
57
|
import { Project } from '@show-karma/karma-gap-sdk';
|
|
@@ -82,8 +87,8 @@ import { GAP } from '@show-karma/karma-gap-sdk';
|
|
|
82
87
|
|
|
83
88
|
const gap = GAP.createClient({
|
|
84
89
|
network: 'optimism-goerli', // sepolia, optimism,
|
|
85
|
-
// apiClient: custom api client, see
|
|
86
|
-
// gelatoOpts: for gasless transactions, see
|
|
90
|
+
// apiClient: custom api client, see it on Chap. 8;
|
|
91
|
+
// gelatoOpts: for gasless transactions, see it on Chap. 7;
|
|
87
92
|
});
|
|
88
93
|
|
|
89
94
|
export default gap;
|
|
@@ -104,7 +109,7 @@ export class MyCustomApiClient extends Fetcher {
|
|
|
104
109
|
}
|
|
105
110
|
```
|
|
106
111
|
|
|
107
|
-
[..] Then you can use it on GapClient. More details about how to implement a custom fetcher on [
|
|
112
|
+
[..] Then you can use it on GapClient. More details about how to implement a custom fetcher on [Chapter 8](#8-custom-api).
|
|
108
113
|
|
|
109
114
|
```ts
|
|
110
115
|
// gap.client.ts;
|
|
@@ -115,7 +120,6 @@ const gap = GAP.createClient({
|
|
|
115
120
|
network: 'optimism-goerli', // sepolia, optimism,
|
|
116
121
|
apiClient: new MyCustomApiClient('https://my-custom-api.mydomain.com'),
|
|
117
122
|
// gelatoOpts: for gasless transactions, see it on Chap. 7;
|
|
118
|
-
// ipfsKey: for cheaper attestations;
|
|
119
123
|
});
|
|
120
124
|
|
|
121
125
|
export default gap;
|
|
@@ -123,11 +127,9 @@ export default gap;
|
|
|
123
127
|
|
|
124
128
|
The `gelatoOpts` option is used when developers aim to provide gasless transactions for a better user experience. For more details about this feature, please refer to [Chapter 7](#7-gasless-transactions-with-gelato).
|
|
125
129
|
|
|
126
|
-
|
|
130
|
+
## 4. Getting Attestations
|
|
127
131
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
After initializing the GAP client, you are now able to fetch entities available including:
|
|
132
|
+
After initializing the GAP client, you are now able to fetch attestations available within this project, including:
|
|
131
133
|
|
|
132
134
|
- Communities
|
|
133
135
|
- Projects
|
|
@@ -137,7 +139,7 @@ After initializing the GAP client, you are now able to fetch entities available
|
|
|
137
139
|
- Milestones
|
|
138
140
|
- Milestone updates
|
|
139
141
|
|
|
140
|
-
Indeed, you can retrieve all available
|
|
142
|
+
Indeed, you can retrieve all available attestations, but we provide methods primarily for the higher-level attestations, as this aligns with the intended behavior. When examining the `Fetcher` interface, you can:
|
|
141
143
|
|
|
142
144
|
- Retrieve communities along with their related grants.
|
|
143
145
|
- Obtain projects, which will contain related members and grants. Note that grants will include related updates and milestones, and milestones will also include their updates.
|
|
@@ -167,9 +169,9 @@ gap.fetch
|
|
|
167
169
|
});
|
|
168
170
|
```
|
|
169
171
|
|
|
170
|
-
## 5.
|
|
172
|
+
## 5. Attesting Data in a Frontend
|
|
171
173
|
|
|
172
|
-
|
|
174
|
+
Attesting data using the GAP SDK is quite straightforward. Developers only need to define what they want to attest, and we provide facilities for this module. To avoid frequent wallet pop-ups for individual entity attestations, we've developed a special contract that handles multiple attestations and their relationships. This means you can transact once and attest multiple times. Let's walk through an example:
|
|
173
175
|
|
|
174
176
|
Suppose a user wants to create a project, and this project will include:
|
|
175
177
|
|
|
@@ -196,7 +198,7 @@ export function getDummyProject() {
|
|
|
196
198
|
// Creating Project
|
|
197
199
|
const project = new Project({
|
|
198
200
|
data: { project: true },
|
|
199
|
-
schema:
|
|
201
|
+
schema: GapSchema.find('Project'),
|
|
200
202
|
// Owner address, usually whoever is connected to the app
|
|
201
203
|
recipient: '0xd7d...25f2',
|
|
202
204
|
});
|
|
@@ -210,13 +212,13 @@ export function getDummyProject() {
|
|
|
210
212
|
links: [{ type: 'github', url: 'https://github.com/my-org' }],
|
|
211
213
|
tags: [{ name: 'DAO' }, { name: 'UI/UX' }],
|
|
212
214
|
},
|
|
213
|
-
schema:
|
|
215
|
+
schema: GapSchema.find('ProjectDetails'),
|
|
214
216
|
recipient: project.recipient,
|
|
215
217
|
});
|
|
216
218
|
|
|
217
219
|
const member_1 = new MemberOf({
|
|
218
220
|
data: { memberOf: true },
|
|
219
|
-
schema:
|
|
221
|
+
schema: GapSchema.find('MemberOf'),
|
|
220
222
|
refUID: pro.uid,
|
|
221
223
|
// member 1 address
|
|
222
224
|
recipient: '0x8dC...A8b4',
|
|
@@ -224,7 +226,7 @@ export function getDummyProject() {
|
|
|
224
226
|
|
|
225
227
|
const member_2 = new MemberOf({
|
|
226
228
|
data: { memberOf: true },
|
|
227
|
-
schema:
|
|
229
|
+
schema: GapSchema.find('MemberOf'),
|
|
228
230
|
refUID: pro.uid,
|
|
229
231
|
// member 2 address
|
|
230
232
|
recipient: '0xabc...A7b3',
|
|
@@ -237,7 +239,7 @@ export function getDummyProject() {
|
|
|
237
239
|
const grant = new Grant({
|
|
238
240
|
// Address of the related community
|
|
239
241
|
data: { communityUID: '0xabc...def' },
|
|
240
|
-
schema:
|
|
242
|
+
schema: GapSchema.find('Grant'),
|
|
241
243
|
recipient: project.recipient,
|
|
242
244
|
});
|
|
243
245
|
|
|
@@ -250,7 +252,7 @@ export function getDummyProject() {
|
|
|
250
252
|
// cycle: grant cycle, optional
|
|
251
253
|
// season: grant season, optional
|
|
252
254
|
},
|
|
253
|
-
schema:
|
|
255
|
+
schema: GapSchema.find('GrantDetails'),
|
|
254
256
|
recipient: pro.recipient,
|
|
255
257
|
});
|
|
256
258
|
|
|
@@ -261,7 +263,7 @@ export function getDummyProject() {
|
|
|
261
263
|
description: 'Milestone Description',
|
|
262
264
|
endsAt: Date.now() + 1000000,
|
|
263
265
|
},
|
|
264
|
-
schema:
|
|
266
|
+
schema: GapSchema.find('Milestone'),
|
|
265
267
|
recipient: pro.recipient,
|
|
266
268
|
});
|
|
267
269
|
|
|
@@ -410,9 +412,9 @@ export const MyComponent: React.FC = () => {
|
|
|
410
412
|
|
|
411
413
|
Following any type of attestation, the SDK will associate UIDs with the objects, making them accessible after the attestation is completed. For instance, if you perform the project attestation with all its dependents, you can retrieve the attestation UID of the project, its details, grants, milestones, and so on.
|
|
412
414
|
|
|
413
|
-
###
|
|
415
|
+
### Revoking an attestation
|
|
414
416
|
|
|
415
|
-
Since every object returned by the Fetcher is also an Attestation, to
|
|
417
|
+
Since every object returned by the Fetcher is also an Attestation, to revoke any attestation, the developer simply needs to call attestation.revoke.
|
|
416
418
|
|
|
417
419
|
```ts
|
|
418
420
|
// revoke-project.ts
|
|
@@ -467,9 +469,9 @@ export async function updateProjectDetails(
|
|
|
467
469
|
|
|
468
470
|
> Note that you cannot update Milestone without losing all of its references.
|
|
469
471
|
|
|
470
|
-
## 6.
|
|
472
|
+
## 6. Attesting data in a Backend
|
|
471
473
|
|
|
472
|
-
To
|
|
474
|
+
To attest data in the backend, follow the same content as provided in [Chapter 5](#5-attesting-data-in-a-frontend). The only distinction between them is that in the backend, you'll need to instantiate an `ethers.js` wallet at runtime to sign attestations.
|
|
473
475
|
|
|
474
476
|
```ts
|
|
475
477
|
import { gap } from 'gap-client';
|
|
@@ -644,10 +646,7 @@ When using a self-contained API to hide API keys, we offer a plug-and-play utili
|
|
|
644
646
|
|
|
645
647
|
```ts
|
|
646
648
|
// pages/api/sponsored-handler.ts
|
|
647
|
-
import {
|
|
648
|
-
type ApiRequest,
|
|
649
|
-
handler as sponsorTxnHandler,
|
|
650
|
-
} from '@show-karma/karma-gap-sdk';
|
|
649
|
+
import { type ApiRequest, handler as sponsorTxnHandler } from '@show-karma/karma-gap-sdk';
|
|
651
650
|
import type { NextApiResponse } from 'next';
|
|
652
651
|
|
|
653
652
|
const handler = (req: ApiRequest, res: NextApiResponse) =>
|
|
@@ -840,7 +839,3 @@ export default gap;
|
|
|
840
839
|
```
|
|
841
840
|
|
|
842
841
|
> Note that your API service should return data that aligns with the interfaces provided by each Attestation for proper compatibility with this SDK. This ensures that the data is structured correctly to work seamlessly with the SDK.
|
|
843
|
-
|
|
844
|
-
## Contact Us
|
|
845
|
-
|
|
846
|
-
If you have any questions on SDK usage, join our discord to get help: https://discord.com/invite/X4fwgzPReJ
|