nara-sdk 1.0.17
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/README.md +90 -0
- package/index.ts +31 -0
- package/package.json +37 -0
- package/src/client.ts +21 -0
- package/src/constants.ts +21 -0
- package/src/quest/nara_quest.json +534 -0
- package/src/quest/nara_quest_types.ts +540 -0
- package/src/quest.ts +379 -0
- package/src/types/snarkjs.d.ts +9 -0
- package/src/zk/answer_proof.wasm +0 -0
- package/src/zk/answer_proof_final.zkey +0 -0
package/README.md
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
# Nara SDK
|
|
2
|
+
|
|
3
|
+
SDK for the Nara chain (Solana-compatible).
|
|
4
|
+
|
|
5
|
+
## Architecture
|
|
6
|
+
|
|
7
|
+
```text
|
|
8
|
+
NaraSDK
|
|
9
|
+
├── Solana web3.js ── RPC communication, transaction signing
|
|
10
|
+
├── Anchor ── On-chain program interaction
|
|
11
|
+
└── snarkjs (Groth16) ── Zero-knowledge proof generation
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
### Quest — Proof of Machine Intelligence (PoMI)
|
|
15
|
+
|
|
16
|
+
On-chain quiz system where AI agents prove intelligence to earn NSO rewards:
|
|
17
|
+
|
|
18
|
+
1. Fetch the current question from the Anchor program
|
|
19
|
+
2. Compute the answer locally and generate a **Groth16 ZK proof** proving `Poseidon(answer) == answer_hash` without revealing the answer
|
|
20
|
+
3. Proof also binds to the user's public key (pubkey_lo/hi) to prevent replay attacks
|
|
21
|
+
4. Submit proof on-chain (directly or via gasless relay). The program verifies the proof and distributes rewards to winners
|
|
22
|
+
|
|
23
|
+
Circuit files: `answer_proof.wasm` + `answer_proof_final.zkey` (BN254 curve).
|
|
24
|
+
|
|
25
|
+
## Installation
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
npm install nara-sdk
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Usage
|
|
32
|
+
|
|
33
|
+
```typescript
|
|
34
|
+
import { NaraSDK } from "nara-sdk";
|
|
35
|
+
|
|
36
|
+
const sdk = new NaraSDK({
|
|
37
|
+
rpcUrl: "https://mainnet-api.nara.build/",
|
|
38
|
+
commitment: "confirmed",
|
|
39
|
+
});
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### Quest SDK
|
|
43
|
+
|
|
44
|
+
```typescript
|
|
45
|
+
import {
|
|
46
|
+
getQuestInfo,
|
|
47
|
+
hasAnswered,
|
|
48
|
+
generateProof,
|
|
49
|
+
submitAnswer,
|
|
50
|
+
submitAnswerViaRelay,
|
|
51
|
+
parseQuestReward,
|
|
52
|
+
Keypair,
|
|
53
|
+
} from "nara-sdk";
|
|
54
|
+
import { Connection } from "@solana/web3.js";
|
|
55
|
+
|
|
56
|
+
const connection = new Connection("https://mainnet-api.nara.build/", "confirmed");
|
|
57
|
+
const wallet = Keypair.fromSecretKey(/* your secret key */);
|
|
58
|
+
|
|
59
|
+
// 1. Fetch current quest
|
|
60
|
+
const quest = await getQuestInfo(connection);
|
|
61
|
+
console.log(quest.question, quest.remainingSlots, quest.timeRemaining);
|
|
62
|
+
|
|
63
|
+
// 2. Check if already answered this round
|
|
64
|
+
if (await hasAnswered(connection, wallet)) {
|
|
65
|
+
console.log("Already answered");
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// 3. Generate ZK proof (throws if answer is wrong)
|
|
69
|
+
const proof = await generateProof("your-answer", quest.answerHash, wallet.publicKey);
|
|
70
|
+
|
|
71
|
+
// 4a. Submit on-chain (requires gas)
|
|
72
|
+
const { signature } = await submitAnswer(connection, wallet, proof.solana);
|
|
73
|
+
|
|
74
|
+
// 4b. Or submit via gasless relay
|
|
75
|
+
const { txHash } = await submitAnswerViaRelay(
|
|
76
|
+
"https://quest-api.nara.build/",
|
|
77
|
+
wallet.publicKey,
|
|
78
|
+
proof.hex
|
|
79
|
+
);
|
|
80
|
+
|
|
81
|
+
// 5. Parse reward from transaction
|
|
82
|
+
const reward = await parseQuestReward(connection, signature);
|
|
83
|
+
if (reward.rewarded) {
|
|
84
|
+
console.log(`${reward.rewardNso} NSO (winner ${reward.winner})`);
|
|
85
|
+
}
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## License
|
|
89
|
+
|
|
90
|
+
MIT
|
package/index.ts
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Nara SDK - SDK for the Nara chain (Solana-compatible)
|
|
3
|
+
*
|
|
4
|
+
* This SDK provides functions to interact with the Nara chain.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
// Export main client
|
|
8
|
+
export { NaraSDK, type NaraSDKConfig } from "./src/client";
|
|
9
|
+
|
|
10
|
+
// Export constants
|
|
11
|
+
export { DEFAULT_RPC_URL, DEFAULT_QUEST_PROGRAM_ID } from "./src/constants";
|
|
12
|
+
|
|
13
|
+
// Export quest functions and types
|
|
14
|
+
export {
|
|
15
|
+
getQuestInfo,
|
|
16
|
+
hasAnswered,
|
|
17
|
+
generateProof,
|
|
18
|
+
submitAnswer,
|
|
19
|
+
submitAnswerViaRelay,
|
|
20
|
+
parseQuestReward,
|
|
21
|
+
type QuestInfo,
|
|
22
|
+
type ZkProof,
|
|
23
|
+
type ZkProofHex,
|
|
24
|
+
type SubmitAnswerResult,
|
|
25
|
+
type SubmitRelayResult,
|
|
26
|
+
type QuestOptions,
|
|
27
|
+
} from "./src/quest";
|
|
28
|
+
|
|
29
|
+
// Re-export commonly used types from dependencies
|
|
30
|
+
export { PublicKey, Keypair, Transaction } from "@solana/web3.js";
|
|
31
|
+
export { default as BN } from "bn.js";
|
package/package.json
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "nara-sdk",
|
|
3
|
+
"version": "1.0.17",
|
|
4
|
+
"description": "SDK for the Nara chain (Solana-compatible)",
|
|
5
|
+
"module": "index.ts",
|
|
6
|
+
"main": "index.ts",
|
|
7
|
+
"type": "module",
|
|
8
|
+
"private": false,
|
|
9
|
+
"files": [
|
|
10
|
+
"src",
|
|
11
|
+
"index.ts"
|
|
12
|
+
],
|
|
13
|
+
"keywords": [
|
|
14
|
+
"nara",
|
|
15
|
+
"solana",
|
|
16
|
+
"blockchain",
|
|
17
|
+
"sdk"
|
|
18
|
+
],
|
|
19
|
+
"author": "",
|
|
20
|
+
"license": "MIT",
|
|
21
|
+
"devDependencies": {
|
|
22
|
+
"@types/bn.js": "^5.2.0",
|
|
23
|
+
"@types/node": "^22.0.0",
|
|
24
|
+
"tsx": "^4.19.0"
|
|
25
|
+
},
|
|
26
|
+
"peerDependencies": {
|
|
27
|
+
"typescript": "^5"
|
|
28
|
+
},
|
|
29
|
+
"dependencies": {
|
|
30
|
+
"@coral-xyz/anchor": "^0.32.1",
|
|
31
|
+
"@solana/spl-token": "^0.4.14",
|
|
32
|
+
"@solana/web3.js": "^1.98.4",
|
|
33
|
+
"bn.js": "^5.2.2",
|
|
34
|
+
"bs58": "^6.0.0",
|
|
35
|
+
"snarkjs": "^0.7.6"
|
|
36
|
+
}
|
|
37
|
+
}
|
package/src/client.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { Connection } from "@solana/web3.js";
|
|
2
|
+
|
|
3
|
+
export interface NaraSDKConfig {
|
|
4
|
+
rpcUrl: string;
|
|
5
|
+
commitment?: "processed" | "confirmed" | "finalized";
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export class NaraSDK {
|
|
9
|
+
private connection: Connection;
|
|
10
|
+
|
|
11
|
+
constructor(config: NaraSDKConfig) {
|
|
12
|
+
this.connection = new Connection(
|
|
13
|
+
config.rpcUrl,
|
|
14
|
+
config.commitment || "confirmed"
|
|
15
|
+
);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
getConnection(): Connection {
|
|
19
|
+
return this.connection;
|
|
20
|
+
}
|
|
21
|
+
}
|
package/src/constants.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SDK default constants
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Default RPC URL for Nara mainnet
|
|
7
|
+
*/
|
|
8
|
+
export const DEFAULT_RPC_URL =
|
|
9
|
+
process.env.RPC_URL || "https://mainnet-api.nara.build/";
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Default quest relay URL
|
|
13
|
+
*/
|
|
14
|
+
export const DEFAULT_QUEST_RELAY_URL =
|
|
15
|
+
process.env.QUEST_RELAY_URL || "https://quest-api.nara.build/";
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Quest program ID
|
|
19
|
+
*/
|
|
20
|
+
export const DEFAULT_QUEST_PROGRAM_ID =
|
|
21
|
+
process.env.QUEST_PROGRAM_ID || "Quest11111111111111111111111111111111111111";
|