nara-sdk 1.0.64 → 1.0.66

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/index.ts CHANGED
@@ -47,6 +47,8 @@ export {
47
47
  setStakeAuthority,
48
48
  makeAdjustFreeStakeIx,
49
49
  adjustFreeStake,
50
+ claimAirdrop,
51
+ setAirdropConfig,
50
52
  getQuestConfig,
51
53
  type QuestInfo,
52
54
  type StakeInfo,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nara-sdk",
3
- "version": "1.0.64",
3
+ "version": "1.0.66",
4
4
  "description": "SDK for the Nara chain (Solana-compatible)",
5
5
  "module": "index.ts",
6
6
  "main": "index.ts",
@@ -411,8 +411,8 @@ export async function getConfig(
411
411
  registerFee: number;
412
412
  pointsSelf: number;
413
413
  pointsReferral: number;
414
- referralRegisterFee: number;
415
- referralFeeShare: number;
414
+ referralDiscountBps: number;
415
+ referralShareBps: number;
416
416
  referralRegisterPoints: number;
417
417
  activityReward: number;
418
418
  referralActivityReward: number;
@@ -422,6 +422,9 @@ export async function getConfig(
422
422
  twitterVerificationPoints: number;
423
423
  tweetVerifyReward: number;
424
424
  tweetVerifyPoints: number;
425
+ registerFee7: number;
426
+ registerFee6: number;
427
+ registerFee5: number;
425
428
  }> {
426
429
  const pid = new PublicKey(options?.programId ?? DEFAULT_AGENT_REGISTRY_PROGRAM_ID);
427
430
  const configPda = getConfigPda(pid);
@@ -439,8 +442,8 @@ export async function getConfig(
439
442
  const registerFee = Number(buf.readBigUInt64LE(offset)); offset += 8;
440
443
  const pointsSelf = Number(buf.readBigUInt64LE(offset)); offset += 8;
441
444
  const pointsReferral = Number(buf.readBigUInt64LE(offset)); offset += 8;
442
- const referralRegisterFee = Number(buf.readBigUInt64LE(offset)); offset += 8;
443
- const referralFeeShare = Number(buf.readBigUInt64LE(offset)); offset += 8;
445
+ const referralDiscountBps = Number(buf.readBigUInt64LE(offset)); offset += 8;
446
+ const referralShareBps = Number(buf.readBigUInt64LE(offset)); offset += 8;
444
447
  const referralRegisterPoints = Number(buf.readBigUInt64LE(offset)); offset += 8;
445
448
  const activityReward = Number(buf.readBigUInt64LE(offset)); offset += 8;
446
449
  const referralActivityReward = Number(buf.readBigUInt64LE(offset)); offset += 8;
@@ -449,8 +452,11 @@ export async function getConfig(
449
452
  const twitterVerificationReward = Number(buf.readBigUInt64LE(offset)); offset += 8;
450
453
  const twitterVerificationPoints = Number(buf.readBigUInt64LE(offset)); offset += 8;
451
454
  const tweetVerifyReward = Number(buf.readBigUInt64LE(offset)); offset += 8;
452
- const tweetVerifyPoints = Number(buf.readBigUInt64LE(offset));
453
- return { admin, feeVault, pointMint, refereeMint, refereeActivityMint, registerFee, pointsSelf, pointsReferral, referralRegisterFee, referralFeeShare, referralRegisterPoints, activityReward, referralActivityReward, twitterVerifier, twitterVerificationFee, twitterVerificationReward, twitterVerificationPoints, tweetVerifyReward, tweetVerifyPoints };
455
+ const tweetVerifyPoints = Number(buf.readBigUInt64LE(offset)); offset += 8;
456
+ const registerFee7 = Number(buf.readBigUInt64LE(offset)); offset += 8;
457
+ const registerFee6 = Number(buf.readBigUInt64LE(offset)); offset += 8;
458
+ const registerFee5 = Number(buf.readBigUInt64LE(offset));
459
+ return { admin, feeVault, pointMint, refereeMint, refereeActivityMint, registerFee, pointsSelf, pointsReferral, referralDiscountBps, referralShareBps, referralRegisterPoints, activityReward, referralActivityReward, twitterVerifier, twitterVerificationFee, twitterVerificationReward, twitterVerificationPoints, tweetVerifyReward, tweetVerifyPoints, registerFee7, registerFee6, registerFee5 };
454
460
  }
455
461
 
456
462
  // ─── Agent CRUD ─────────────────────────────────────────────────
@@ -1004,13 +1010,19 @@ export async function withdrawFees(
1004
1010
  export async function updateRegisterFee(
1005
1011
  connection: Connection,
1006
1012
  wallet: Keypair,
1007
- newFee: number | BN,
1013
+ fee: number | BN,
1014
+ fee7: number | BN,
1015
+ fee6: number | BN,
1016
+ fee5: number | BN,
1008
1017
  options?: AgentRegistryOptions
1009
1018
  ): Promise<string> {
1010
1019
  const program = createProgram(connection, wallet, options?.programId);
1011
- const fee = typeof newFee === "number" ? new BN(newFee) : newFee;
1020
+ const f = typeof fee === "number" ? new BN(fee) : fee;
1021
+ const f7 = typeof fee7 === "number" ? new BN(fee7) : fee7;
1022
+ const f6 = typeof fee6 === "number" ? new BN(fee6) : fee6;
1023
+ const f5 = typeof fee5 === "number" ? new BN(fee5) : fee5;
1012
1024
  const ix = await program.methods
1013
- .updateRegisterFee(fee)
1025
+ .updateRegisterFee(f, f7, f6, f5)
1014
1026
  .accounts({ admin: wallet.publicKey } as any)
1015
1027
  .instruction();
1016
1028
  return sendTx(connection, wallet, [ix]);
@@ -1046,17 +1058,17 @@ export async function updatePointsConfig(
1046
1058
  export async function updateReferralConfig(
1047
1059
  connection: Connection,
1048
1060
  wallet: Keypair,
1049
- referralRegisterFee: number | BN,
1050
- referralFeeShare: number | BN,
1061
+ referralDiscountBps: number | BN,
1062
+ referralShareBps: number | BN,
1051
1063
  referralRegisterPoints: number | BN,
1052
1064
  options?: AgentRegistryOptions
1053
1065
  ): Promise<string> {
1054
1066
  const program = createProgram(connection, wallet, options?.programId);
1055
- const fee = typeof referralRegisterFee === "number" ? new BN(referralRegisterFee) : referralRegisterFee;
1056
- const share = typeof referralFeeShare === "number" ? new BN(referralFeeShare) : referralFeeShare;
1067
+ const discount = typeof referralDiscountBps === "number" ? new BN(referralDiscountBps) : referralDiscountBps;
1068
+ const share = typeof referralShareBps === "number" ? new BN(referralShareBps) : referralShareBps;
1057
1069
  const pts = typeof referralRegisterPoints === "number" ? new BN(referralRegisterPoints) : referralRegisterPoints;
1058
1070
  const ix = await program.methods
1059
- .updateReferralConfig(fee, share, pts)
1071
+ .updateReferralConfig(discount, share, pts)
1060
1072
  .accounts({ admin: wallet.publicKey } as any)
1061
1073
  .instruction();
1062
1074
  return sendTx(connection, wallet, [ix]);
@@ -3290,11 +3290,11 @@
3290
3290
  ],
3291
3291
  "args": [
3292
3292
  {
3293
- "name": "referral_register_fee",
3293
+ "name": "referral_discount_bps",
3294
3294
  "type": "u64"
3295
3295
  },
3296
3296
  {
3297
- "name": "referral_fee_share",
3297
+ "name": "referral_share_bps",
3298
3298
  "type": "u64"
3299
3299
  },
3300
3300
  {
@@ -3345,7 +3345,19 @@
3345
3345
  ],
3346
3346
  "args": [
3347
3347
  {
3348
- "name": "new_fee",
3348
+ "name": "fee",
3349
+ "type": "u64"
3350
+ },
3351
+ {
3352
+ "name": "fee_7",
3353
+ "type": "u64"
3354
+ },
3355
+ {
3356
+ "name": "fee_6",
3357
+ "type": "u64"
3358
+ },
3359
+ {
3360
+ "name": "fee_5",
3349
3361
  "type": "u64"
3350
3362
  }
3351
3363
  ]
@@ -4154,6 +4166,32 @@
4154
4166
  74,
4155
4167
  39
4156
4168
  ]
4169
+ },
4170
+ {
4171
+ "name": "TwitterBindRequested",
4172
+ "discriminator": [
4173
+ 251,
4174
+ 254,
4175
+ 188,
4176
+ 154,
4177
+ 25,
4178
+ 126,
4179
+ 76,
4180
+ 169
4181
+ ]
4182
+ },
4183
+ {
4184
+ "name": "TwitterBindResult",
4185
+ "discriminator": [
4186
+ 4,
4187
+ 160,
4188
+ 91,
4189
+ 219,
4190
+ 142,
4191
+ 73,
4192
+ 75,
4193
+ 215
4194
+ ]
4157
4195
  }
4158
4196
  ],
4159
4197
  "errors": [
@@ -4386,6 +4424,11 @@
4386
4424
  "code": 6045,
4387
4425
  "name": "TweetAlreadyApproved",
4388
4426
  "msg": "Tweet has already been approved"
4427
+ },
4428
+ {
4429
+ "code": 6046,
4430
+ "name": "AgentIdReserved",
4431
+ "msg": "Agent ID length <= 4 is reserved for admin only"
4389
4432
  }
4390
4433
  ],
4391
4434
  "types": [
@@ -4675,11 +4718,11 @@
4675
4718
  "type": "u64"
4676
4719
  },
4677
4720
  {
4678
- "name": "referral_register_fee",
4721
+ "name": "referral_discount_bps",
4679
4722
  "type": "u64"
4680
4723
  },
4681
4724
  {
4682
- "name": "referral_fee_share",
4725
+ "name": "referral_share_bps",
4683
4726
  "type": "u64"
4684
4727
  },
4685
4728
  {
@@ -4718,6 +4761,18 @@
4718
4761
  "name": "tweet_verify_points",
4719
4762
  "type": "u64"
4720
4763
  },
4764
+ {
4765
+ "name": "register_fee_7",
4766
+ "type": "u64"
4767
+ },
4768
+ {
4769
+ "name": "register_fee_6",
4770
+ "type": "u64"
4771
+ },
4772
+ {
4773
+ "name": "register_fee_5",
4774
+ "type": "u64"
4775
+ },
4721
4776
  {
4722
4777
  "name": "_reserved",
4723
4778
  "type": {
@@ -4735,15 +4790,6 @@
4735
4790
  96
4736
4791
  ]
4737
4792
  }
4738
- },
4739
- {
4740
- "name": "_reserved3",
4741
- "type": {
4742
- "array": [
4743
- "u8",
4744
- 24
4745
- ]
4746
- }
4747
4793
  }
4748
4794
  ]
4749
4795
  }
@@ -4907,6 +4953,78 @@
4907
4953
  ]
4908
4954
  }
4909
4955
  },
4956
+ {
4957
+ "name": "TwitterBindRequested",
4958
+ "type": {
4959
+ "kind": "struct",
4960
+ "fields": [
4961
+ {
4962
+ "name": "agent_id",
4963
+ "type": "string"
4964
+ },
4965
+ {
4966
+ "name": "authority",
4967
+ "type": "pubkey"
4968
+ },
4969
+ {
4970
+ "name": "username",
4971
+ "type": "string"
4972
+ },
4973
+ {
4974
+ "name": "fee",
4975
+ "type": "u64"
4976
+ },
4977
+ {
4978
+ "name": "is_first_bind",
4979
+ "type": "bool"
4980
+ },
4981
+ {
4982
+ "name": "timestamp",
4983
+ "type": "i64"
4984
+ }
4985
+ ]
4986
+ }
4987
+ },
4988
+ {
4989
+ "name": "TwitterBindResult",
4990
+ "type": {
4991
+ "kind": "struct",
4992
+ "fields": [
4993
+ {
4994
+ "name": "agent_id",
4995
+ "type": "string"
4996
+ },
4997
+ {
4998
+ "name": "authority",
4999
+ "type": "pubkey"
5000
+ },
5001
+ {
5002
+ "name": "username",
5003
+ "type": "string"
5004
+ },
5005
+ {
5006
+ "name": "approved",
5007
+ "type": "bool"
5008
+ },
5009
+ {
5010
+ "name": "fee_refunded",
5011
+ "type": "u64"
5012
+ },
5013
+ {
5014
+ "name": "reward",
5015
+ "type": "u64"
5016
+ },
5017
+ {
5018
+ "name": "points",
5019
+ "type": "u64"
5020
+ },
5021
+ {
5022
+ "name": "timestamp",
5023
+ "type": "i64"
5024
+ }
5025
+ ]
5026
+ }
5027
+ },
4910
5028
  {
4911
5029
  "name": "TwitterHandle",
4912
5030
  "serialization": "bytemuck",
@@ -3296,11 +3296,11 @@ export type NaraAgentRegistry = {
3296
3296
  ],
3297
3297
  "args": [
3298
3298
  {
3299
- "name": "referralRegisterFee",
3299
+ "name": "referralDiscountBps",
3300
3300
  "type": "u64"
3301
3301
  },
3302
3302
  {
3303
- "name": "referralFeeShare",
3303
+ "name": "referralShareBps",
3304
3304
  "type": "u64"
3305
3305
  },
3306
3306
  {
@@ -3351,7 +3351,19 @@ export type NaraAgentRegistry = {
3351
3351
  ],
3352
3352
  "args": [
3353
3353
  {
3354
- "name": "newFee",
3354
+ "name": "fee",
3355
+ "type": "u64"
3356
+ },
3357
+ {
3358
+ "name": "fee7",
3359
+ "type": "u64"
3360
+ },
3361
+ {
3362
+ "name": "fee6",
3363
+ "type": "u64"
3364
+ },
3365
+ {
3366
+ "name": "fee5",
3355
3367
  "type": "u64"
3356
3368
  }
3357
3369
  ]
@@ -4160,6 +4172,32 @@ export type NaraAgentRegistry = {
4160
4172
  74,
4161
4173
  39
4162
4174
  ]
4175
+ },
4176
+ {
4177
+ "name": "twitterBindRequested",
4178
+ "discriminator": [
4179
+ 251,
4180
+ 254,
4181
+ 188,
4182
+ 154,
4183
+ 25,
4184
+ 126,
4185
+ 76,
4186
+ 169
4187
+ ]
4188
+ },
4189
+ {
4190
+ "name": "twitterBindResult",
4191
+ "discriminator": [
4192
+ 4,
4193
+ 160,
4194
+ 91,
4195
+ 219,
4196
+ 142,
4197
+ 73,
4198
+ 75,
4199
+ 215
4200
+ ]
4163
4201
  }
4164
4202
  ],
4165
4203
  "errors": [
@@ -4392,6 +4430,11 @@ export type NaraAgentRegistry = {
4392
4430
  "code": 6045,
4393
4431
  "name": "tweetAlreadyApproved",
4394
4432
  "msg": "Tweet has already been approved"
4433
+ },
4434
+ {
4435
+ "code": 6046,
4436
+ "name": "agentIdReserved",
4437
+ "msg": "Agent ID length <= 4 is reserved for admin only"
4395
4438
  }
4396
4439
  ],
4397
4440
  "types": [
@@ -4681,11 +4724,11 @@ export type NaraAgentRegistry = {
4681
4724
  "type": "u64"
4682
4725
  },
4683
4726
  {
4684
- "name": "referralRegisterFee",
4727
+ "name": "referralDiscountBps",
4685
4728
  "type": "u64"
4686
4729
  },
4687
4730
  {
4688
- "name": "referralFeeShare",
4731
+ "name": "referralShareBps",
4689
4732
  "type": "u64"
4690
4733
  },
4691
4734
  {
@@ -4724,6 +4767,18 @@ export type NaraAgentRegistry = {
4724
4767
  "name": "tweetVerifyPoints",
4725
4768
  "type": "u64"
4726
4769
  },
4770
+ {
4771
+ "name": "registerFee7",
4772
+ "type": "u64"
4773
+ },
4774
+ {
4775
+ "name": "registerFee6",
4776
+ "type": "u64"
4777
+ },
4778
+ {
4779
+ "name": "registerFee5",
4780
+ "type": "u64"
4781
+ },
4727
4782
  {
4728
4783
  "name": "reserved",
4729
4784
  "type": {
@@ -4741,15 +4796,6 @@ export type NaraAgentRegistry = {
4741
4796
  96
4742
4797
  ]
4743
4798
  }
4744
- },
4745
- {
4746
- "name": "reserved3",
4747
- "type": {
4748
- "array": [
4749
- "u8",
4750
- 24
4751
- ]
4752
- }
4753
4799
  }
4754
4800
  ]
4755
4801
  }
@@ -4913,6 +4959,78 @@ export type NaraAgentRegistry = {
4913
4959
  ]
4914
4960
  }
4915
4961
  },
4962
+ {
4963
+ "name": "twitterBindRequested",
4964
+ "type": {
4965
+ "kind": "struct",
4966
+ "fields": [
4967
+ {
4968
+ "name": "agentId",
4969
+ "type": "string"
4970
+ },
4971
+ {
4972
+ "name": "authority",
4973
+ "type": "pubkey"
4974
+ },
4975
+ {
4976
+ "name": "username",
4977
+ "type": "string"
4978
+ },
4979
+ {
4980
+ "name": "fee",
4981
+ "type": "u64"
4982
+ },
4983
+ {
4984
+ "name": "isFirstBind",
4985
+ "type": "bool"
4986
+ },
4987
+ {
4988
+ "name": "timestamp",
4989
+ "type": "i64"
4990
+ }
4991
+ ]
4992
+ }
4993
+ },
4994
+ {
4995
+ "name": "twitterBindResult",
4996
+ "type": {
4997
+ "kind": "struct",
4998
+ "fields": [
4999
+ {
5000
+ "name": "agentId",
5001
+ "type": "string"
5002
+ },
5003
+ {
5004
+ "name": "authority",
5005
+ "type": "pubkey"
5006
+ },
5007
+ {
5008
+ "name": "username",
5009
+ "type": "string"
5010
+ },
5011
+ {
5012
+ "name": "approved",
5013
+ "type": "bool"
5014
+ },
5015
+ {
5016
+ "name": "feeRefunded",
5017
+ "type": "u64"
5018
+ },
5019
+ {
5020
+ "name": "reward",
5021
+ "type": "u64"
5022
+ },
5023
+ {
5024
+ "name": "points",
5025
+ "type": "u64"
5026
+ },
5027
+ {
5028
+ "name": "timestamp",
5029
+ "type": "i64"
5030
+ }
5031
+ ]
5032
+ }
5033
+ },
4916
5034
  {
4917
5035
  "name": "twitterHandle",
4918
5036
  "serialization": "bytemuck",
@@ -96,6 +96,136 @@
96
96
  }
97
97
  ]
98
98
  },
99
+ {
100
+ "name": "claim_airdrop",
101
+ "discriminator": [
102
+ 137,
103
+ 50,
104
+ 122,
105
+ 111,
106
+ 89,
107
+ 254,
108
+ 8,
109
+ 20
110
+ ],
111
+ "accounts": [
112
+ {
113
+ "name": "game_config",
114
+ "pda": {
115
+ "seeds": [
116
+ {
117
+ "kind": "const",
118
+ "value": [
119
+ 113,
120
+ 117,
121
+ 101,
122
+ 115,
123
+ 116,
124
+ 95,
125
+ 99,
126
+ 111,
127
+ 110,
128
+ 102,
129
+ 105,
130
+ 103
131
+ ]
132
+ }
133
+ ]
134
+ }
135
+ },
136
+ {
137
+ "name": "pool",
138
+ "pda": {
139
+ "seeds": [
140
+ {
141
+ "kind": "const",
142
+ "value": [
143
+ 113,
144
+ 117,
145
+ 101,
146
+ 115,
147
+ 116,
148
+ 95,
149
+ 112,
150
+ 111,
151
+ 111,
152
+ 108
153
+ ]
154
+ }
155
+ ]
156
+ }
157
+ },
158
+ {
159
+ "name": "winner_record",
160
+ "writable": true,
161
+ "pda": {
162
+ "seeds": [
163
+ {
164
+ "kind": "const",
165
+ "value": [
166
+ 113,
167
+ 117,
168
+ 101,
169
+ 115,
170
+ 116,
171
+ 95,
172
+ 119,
173
+ 105,
174
+ 110,
175
+ 110,
176
+ 101,
177
+ 114
178
+ ]
179
+ },
180
+ {
181
+ "kind": "account",
182
+ "path": "user"
183
+ }
184
+ ]
185
+ }
186
+ },
187
+ {
188
+ "name": "airdrop_fund",
189
+ "writable": true,
190
+ "pda": {
191
+ "seeds": [
192
+ {
193
+ "kind": "const",
194
+ "value": [
195
+ 113,
196
+ 117,
197
+ 101,
198
+ 115,
199
+ 116,
200
+ 95,
201
+ 97,
202
+ 105,
203
+ 114,
204
+ 100,
205
+ 114,
206
+ 111,
207
+ 112
208
+ ]
209
+ }
210
+ ]
211
+ }
212
+ },
213
+ {
214
+ "name": "user",
215
+ "writable": true
216
+ },
217
+ {
218
+ "name": "payer",
219
+ "writable": true,
220
+ "signer": true
221
+ },
222
+ {
223
+ "name": "system_program",
224
+ "address": "11111111111111111111111111111111"
225
+ }
226
+ ],
227
+ "args": []
228
+ },
99
229
  {
100
230
  "name": "create_question",
101
231
  "discriminator": [
@@ -343,6 +473,60 @@
343
473
  ],
344
474
  "args": []
345
475
  },
476
+ {
477
+ "name": "set_airdrop_config",
478
+ "discriminator": [
479
+ 255,
480
+ 181,
481
+ 252,
482
+ 34,
483
+ 155,
484
+ 230,
485
+ 65,
486
+ 227
487
+ ],
488
+ "accounts": [
489
+ {
490
+ "name": "game_config",
491
+ "writable": true,
492
+ "pda": {
493
+ "seeds": [
494
+ {
495
+ "kind": "const",
496
+ "value": [
497
+ 113,
498
+ 117,
499
+ 101,
500
+ 115,
501
+ 116,
502
+ 95,
503
+ 99,
504
+ 111,
505
+ 110,
506
+ 102,
507
+ 105,
508
+ 103
509
+ ]
510
+ }
511
+ ]
512
+ }
513
+ },
514
+ {
515
+ "name": "authority",
516
+ "signer": true
517
+ }
518
+ ],
519
+ "args": [
520
+ {
521
+ "name": "airdrop_amount",
522
+ "type": "u64"
523
+ },
524
+ {
525
+ "name": "max_airdrop_count",
526
+ "type": "u32"
527
+ }
528
+ ]
529
+ },
346
530
  {
347
531
  "name": "set_quest_authority",
348
532
  "discriminator": [
@@ -1618,6 +1802,31 @@
1618
1802
  "code": 6017,
1619
1803
  "name": "FreeCreditsOverflow",
1620
1804
  "msg": "Free credits overflow"
1805
+ },
1806
+ {
1807
+ "code": 6018,
1808
+ "name": "AirdropNotEligible",
1809
+ "msg": "Not eligible: must answer current round first"
1810
+ },
1811
+ {
1812
+ "code": 6019,
1813
+ "name": "AirdropMaxReached",
1814
+ "msg": "Max airdrop count reached for this address"
1815
+ },
1816
+ {
1817
+ "code": 6020,
1818
+ "name": "AirdropCooldown",
1819
+ "msg": "Must wait 24 hours between airdrop claims"
1820
+ },
1821
+ {
1822
+ "code": 6021,
1823
+ "name": "AirdropDisabled",
1824
+ "msg": "Airdrop is disabled (amount = 0)"
1825
+ },
1826
+ {
1827
+ "code": 6022,
1828
+ "name": "InsufficientAirdrop",
1829
+ "msg": "Airdrop fund has insufficient balance"
1621
1830
  }
1622
1831
  ],
1623
1832
  "types": [
@@ -1706,12 +1915,20 @@
1706
1915
  "name": "stake_authority",
1707
1916
  "type": "pubkey"
1708
1917
  },
1918
+ {
1919
+ "name": "airdrop_amount",
1920
+ "type": "u64"
1921
+ },
1922
+ {
1923
+ "name": "max_airdrop_count",
1924
+ "type": "u32"
1925
+ },
1709
1926
  {
1710
1927
  "name": "_padding",
1711
1928
  "type": {
1712
1929
  "array": [
1713
1930
  "u8",
1714
- 32
1931
+ 20
1715
1932
  ]
1716
1933
  }
1717
1934
  }
@@ -1826,12 +2043,20 @@
1826
2043
  "name": "round",
1827
2044
  "type": "u64"
1828
2045
  },
2046
+ {
2047
+ "name": "airdrop_count",
2048
+ "type": "u32"
2049
+ },
2050
+ {
2051
+ "name": "last_airdrop_ts",
2052
+ "type": "i64"
2053
+ },
1829
2054
  {
1830
2055
  "name": "_padding",
1831
2056
  "type": {
1832
2057
  "array": [
1833
2058
  "u8",
1834
- 64
2059
+ 52
1835
2060
  ]
1836
2061
  }
1837
2062
  }
@@ -102,6 +102,136 @@ export type NaraQuest = {
102
102
  }
103
103
  ]
104
104
  },
105
+ {
106
+ "name": "claimAirdrop",
107
+ "discriminator": [
108
+ 137,
109
+ 50,
110
+ 122,
111
+ 111,
112
+ 89,
113
+ 254,
114
+ 8,
115
+ 20
116
+ ],
117
+ "accounts": [
118
+ {
119
+ "name": "gameConfig",
120
+ "pda": {
121
+ "seeds": [
122
+ {
123
+ "kind": "const",
124
+ "value": [
125
+ 113,
126
+ 117,
127
+ 101,
128
+ 115,
129
+ 116,
130
+ 95,
131
+ 99,
132
+ 111,
133
+ 110,
134
+ 102,
135
+ 105,
136
+ 103
137
+ ]
138
+ }
139
+ ]
140
+ }
141
+ },
142
+ {
143
+ "name": "pool",
144
+ "pda": {
145
+ "seeds": [
146
+ {
147
+ "kind": "const",
148
+ "value": [
149
+ 113,
150
+ 117,
151
+ 101,
152
+ 115,
153
+ 116,
154
+ 95,
155
+ 112,
156
+ 111,
157
+ 111,
158
+ 108
159
+ ]
160
+ }
161
+ ]
162
+ }
163
+ },
164
+ {
165
+ "name": "winnerRecord",
166
+ "writable": true,
167
+ "pda": {
168
+ "seeds": [
169
+ {
170
+ "kind": "const",
171
+ "value": [
172
+ 113,
173
+ 117,
174
+ 101,
175
+ 115,
176
+ 116,
177
+ 95,
178
+ 119,
179
+ 105,
180
+ 110,
181
+ 110,
182
+ 101,
183
+ 114
184
+ ]
185
+ },
186
+ {
187
+ "kind": "account",
188
+ "path": "user"
189
+ }
190
+ ]
191
+ }
192
+ },
193
+ {
194
+ "name": "airdropFund",
195
+ "writable": true,
196
+ "pda": {
197
+ "seeds": [
198
+ {
199
+ "kind": "const",
200
+ "value": [
201
+ 113,
202
+ 117,
203
+ 101,
204
+ 115,
205
+ 116,
206
+ 95,
207
+ 97,
208
+ 105,
209
+ 114,
210
+ 100,
211
+ 114,
212
+ 111,
213
+ 112
214
+ ]
215
+ }
216
+ ]
217
+ }
218
+ },
219
+ {
220
+ "name": "user",
221
+ "writable": true
222
+ },
223
+ {
224
+ "name": "payer",
225
+ "writable": true,
226
+ "signer": true
227
+ },
228
+ {
229
+ "name": "systemProgram",
230
+ "address": "11111111111111111111111111111111"
231
+ }
232
+ ],
233
+ "args": []
234
+ },
105
235
  {
106
236
  "name": "createQuestion",
107
237
  "discriminator": [
@@ -349,6 +479,60 @@ export type NaraQuest = {
349
479
  ],
350
480
  "args": []
351
481
  },
482
+ {
483
+ "name": "setAirdropConfig",
484
+ "discriminator": [
485
+ 255,
486
+ 181,
487
+ 252,
488
+ 34,
489
+ 155,
490
+ 230,
491
+ 65,
492
+ 227
493
+ ],
494
+ "accounts": [
495
+ {
496
+ "name": "gameConfig",
497
+ "writable": true,
498
+ "pda": {
499
+ "seeds": [
500
+ {
501
+ "kind": "const",
502
+ "value": [
503
+ 113,
504
+ 117,
505
+ 101,
506
+ 115,
507
+ 116,
508
+ 95,
509
+ 99,
510
+ 111,
511
+ 110,
512
+ 102,
513
+ 105,
514
+ 103
515
+ ]
516
+ }
517
+ ]
518
+ }
519
+ },
520
+ {
521
+ "name": "authority",
522
+ "signer": true
523
+ }
524
+ ],
525
+ "args": [
526
+ {
527
+ "name": "airdropAmount",
528
+ "type": "u64"
529
+ },
530
+ {
531
+ "name": "maxAirdropCount",
532
+ "type": "u32"
533
+ }
534
+ ]
535
+ },
352
536
  {
353
537
  "name": "setQuestAuthority",
354
538
  "discriminator": [
@@ -1624,6 +1808,31 @@ export type NaraQuest = {
1624
1808
  "code": 6017,
1625
1809
  "name": "freeCreditsOverflow",
1626
1810
  "msg": "Free credits overflow"
1811
+ },
1812
+ {
1813
+ "code": 6018,
1814
+ "name": "airdropNotEligible",
1815
+ "msg": "Not eligible: must answer current round first"
1816
+ },
1817
+ {
1818
+ "code": 6019,
1819
+ "name": "airdropMaxReached",
1820
+ "msg": "Max airdrop count reached for this address"
1821
+ },
1822
+ {
1823
+ "code": 6020,
1824
+ "name": "airdropCooldown",
1825
+ "msg": "Must wait 24 hours between airdrop claims"
1826
+ },
1827
+ {
1828
+ "code": 6021,
1829
+ "name": "airdropDisabled",
1830
+ "msg": "Airdrop is disabled (amount = 0)"
1831
+ },
1832
+ {
1833
+ "code": 6022,
1834
+ "name": "insufficientAirdrop",
1835
+ "msg": "Airdrop fund has insufficient balance"
1627
1836
  }
1628
1837
  ],
1629
1838
  "types": [
@@ -1712,12 +1921,20 @@ export type NaraQuest = {
1712
1921
  "name": "stakeAuthority",
1713
1922
  "type": "pubkey"
1714
1923
  },
1924
+ {
1925
+ "name": "airdropAmount",
1926
+ "type": "u64"
1927
+ },
1928
+ {
1929
+ "name": "maxAirdropCount",
1930
+ "type": "u32"
1931
+ },
1715
1932
  {
1716
1933
  "name": "padding",
1717
1934
  "type": {
1718
1935
  "array": [
1719
1936
  "u8",
1720
- 32
1937
+ 20
1721
1938
  ]
1722
1939
  }
1723
1940
  }
@@ -1832,12 +2049,20 @@ export type NaraQuest = {
1832
2049
  "name": "round",
1833
2050
  "type": "u64"
1834
2051
  },
2052
+ {
2053
+ "name": "airdropCount",
2054
+ "type": "u32"
2055
+ },
2056
+ {
2057
+ "name": "lastAirdropTs",
2058
+ "type": "i64"
2059
+ },
1835
2060
  {
1836
2061
  "name": "padding",
1837
2062
  "type": {
1838
2063
  "array": [
1839
2064
  "u8",
1840
- 64
2065
+ 52
1841
2066
  ]
1842
2067
  }
1843
2068
  }
@@ -977,7 +977,7 @@
977
977
  {
978
978
  "code": 6000,
979
979
  "name": "NameTooShort",
980
- "msg": "Name too short: min 5 bytes"
980
+ "msg": "Name too short: min 4 bytes"
981
981
  },
982
982
  {
983
983
  "code": 6001,
@@ -1359,7 +1359,7 @@
1359
1359
  {
1360
1360
  "name": "name",
1361
1361
  "docs": [
1362
- "Globally unique name (min 5 bytes, max 32 bytes)."
1362
+ "Globally unique name (min 4 bytes, max 32 bytes)."
1363
1363
  ],
1364
1364
  "type": {
1365
1365
  "array": [
@@ -983,7 +983,7 @@ export type NaraSkillsHub = {
983
983
  {
984
984
  "code": 6000,
985
985
  "name": "nameTooShort",
986
- "msg": "Name too short: min 5 bytes"
986
+ "msg": "Name too short: min 4 bytes"
987
987
  },
988
988
  {
989
989
  "code": 6001,
@@ -1365,7 +1365,7 @@ export type NaraSkillsHub = {
1365
1365
  {
1366
1366
  "name": "name",
1367
1367
  "docs": [
1368
- "Globally unique name (min 5 bytes, max 32 bytes)."
1368
+ "Globally unique name (min 4 bytes, max 32 bytes)."
1369
1369
  ],
1370
1370
  "type": {
1371
1371
  "array": [
package/src/quest.ts CHANGED
@@ -853,6 +853,8 @@ export async function getQuestConfig(
853
853
  rewardPerShare: number;
854
854
  extraReward: number;
855
855
  stakeAuthority: PublicKey;
856
+ airdropAmount: number;
857
+ maxAirdropCount: number;
856
858
  }> {
857
859
  const kp = Keypair.generate();
858
860
  const program = createProgram(connection, kp, options?.programId);
@@ -875,6 +877,8 @@ export async function getQuestConfig(
875
877
  rewardPerShare: Number(config.rewardPerShare.toString()),
876
878
  extraReward: Number(config.extraReward.toString()),
877
879
  stakeAuthority: config.stakeAuthority,
880
+ airdropAmount: Number(config.airdropAmount.toString()),
881
+ maxAirdropCount: config.maxAirdropCount,
878
882
  };
879
883
  }
880
884
 
@@ -930,3 +934,42 @@ export async function adjustFreeStake(
930
934
  const ix = await makeAdjustFreeStakeIx(connection, wallet.publicKey, user, delta, reason, options);
931
935
  return sendTx(connection, wallet, [ix]);
932
936
  }
937
+
938
+ /**
939
+ * Claim airdrop for a user. The payer pays for the transaction.
940
+ * @param user - The user to claim airdrop for
941
+ */
942
+ export async function claimAirdrop(
943
+ connection: Connection,
944
+ wallet: Keypair,
945
+ user: PublicKey,
946
+ options?: QuestOptions
947
+ ): Promise<string> {
948
+ const program = createProgram(connection, wallet, options?.programId);
949
+ const ix = await program.methods
950
+ .claimAirdrop()
951
+ .accounts({ user, payer: wallet.publicKey } as any)
952
+ .instruction();
953
+ return sendTx(connection, wallet, [ix]);
954
+ }
955
+
956
+ /**
957
+ * Set airdrop configuration (authority only).
958
+ * @param airdropAmount - Amount per airdrop in lamports
959
+ * @param maxAirdropCount - Maximum number of airdrops per user
960
+ */
961
+ export async function setAirdropConfig(
962
+ connection: Connection,
963
+ wallet: Keypair,
964
+ airdropAmount: number | BN,
965
+ maxAirdropCount: number,
966
+ options?: QuestOptions
967
+ ): Promise<string> {
968
+ const program = createProgram(connection, wallet, options?.programId);
969
+ const amt = typeof airdropAmount === "number" ? new BN(airdropAmount) : airdropAmount;
970
+ const ix = await program.methods
971
+ .setAirdropConfig(amt, maxAirdropCount)
972
+ .accounts({ authority: wallet.publicKey } as any)
973
+ .instruction();
974
+ return sendTx(connection, wallet, [ix]);
975
+ }