nara-sdk 1.0.80 → 1.0.82

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 CHANGED
@@ -109,6 +109,7 @@ console.log(status.deliverySignature); // destination tx
109
109
  | Token | Solana side | Nara side | Decimals |
110
110
  |---|---|---|---|
111
111
  | USDC | collateral (lock) | synthetic (mint, Token-2022) | 6 |
112
+ | USDT | collateral (lock) | synthetic (mint, Token-2022) | 6 |
112
113
  | SOL | native (lamports) | synthetic (mint, Token-2022) | 9 |
113
114
 
114
115
  Add new tokens at runtime:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nara-sdk",
3
- "version": "1.0.80",
3
+ "version": "1.0.82",
4
4
  "description": "SDK for the Nara chain (Solana-compatible)",
5
5
  "module": "index.ts",
6
6
  "main": "index.ts",
package/src/bridge.ts CHANGED
@@ -49,6 +49,8 @@ export interface BridgeTokenSide {
49
49
  export interface BridgeTokenConfig {
50
50
  symbol: string;
51
51
  decimals: number;
52
+ /** Minimum per-transfer amount in raw units (rejected if below) */
53
+ minAmount: bigint;
52
54
  solana: BridgeTokenSide;
53
55
  nara: BridgeTokenSide;
54
56
  }
@@ -128,6 +130,7 @@ export const BRIDGE_TOKENS: Record<string, BridgeTokenConfig> = {
128
130
  USDC: {
129
131
  symbol: "USDC",
130
132
  decimals: 6,
133
+ minAmount: 100_000n, // 0.1 USDC
131
134
  solana: {
132
135
  warpProgram: new PublicKey("4GcZJTa8s9vxtTz97Vj1RrwKMqPkT3DiiJkvUQDwsuZP"),
133
136
  mode: "collateral",
@@ -144,6 +147,7 @@ export const BRIDGE_TOKENS: Record<string, BridgeTokenConfig> = {
144
147
  USDT: {
145
148
  symbol: "USDT",
146
149
  decimals: 6,
150
+ minAmount: 100_000n, // 0.1 USDT
147
151
  solana: {
148
152
  warpProgram: new PublicKey("DCTt9H3pwwU89qC3Z4voYNThZypV68AwhYNzMNBxWXoy"),
149
153
  mode: "collateral",
@@ -160,6 +164,7 @@ export const BRIDGE_TOKENS: Record<string, BridgeTokenConfig> = {
160
164
  SOL: {
161
165
  symbol: "SOL",
162
166
  decimals: 9,
167
+ minAmount: 1_000_000n, // 0.001 SOL
163
168
  solana: {
164
169
  warpProgram: new PublicKey("46MmAWwKRAt9uvn7m44NXbVq2DCWBQE2r1TDw25nyXrt"),
165
170
  mode: "native",
@@ -523,6 +528,15 @@ export function makeBridgeIxs(params: BridgeTransferParams): BridgeIxsResult {
523
528
 
524
529
  if (amount <= 0n) throw new Error("amount must be > 0");
525
530
 
531
+ // Enforce per-token minimum transfer amount
532
+ const tokenCfg = getToken(token);
533
+ if (amount < tokenCfg.minAmount) {
534
+ const min = Number(tokenCfg.minAmount) / Math.pow(10, tokenCfg.decimals);
535
+ throw new Error(
536
+ `Bridge amount too small: minimum for ${token} is ${min} (raw ${tokenCfg.minAmount})`
537
+ );
538
+ }
539
+
526
540
  const split = skipFee
527
541
  ? { feeAmount: 0n, bridgeAmount: amount, feeBps: 0 }
528
542
  : calculateBridgeFee(amount, feeBps);
@@ -2507,6 +2507,129 @@
2507
2507
  }
2508
2508
  ]
2509
2509
  },
2510
+ {
2511
+ "name": "reject_twitter_with_reason",
2512
+ "discriminator": [
2513
+ 3,
2514
+ 212,
2515
+ 79,
2516
+ 37,
2517
+ 41,
2518
+ 111,
2519
+ 209,
2520
+ 83
2521
+ ],
2522
+ "accounts": [
2523
+ {
2524
+ "name": "verifier",
2525
+ "writable": true,
2526
+ "signer": true
2527
+ },
2528
+ {
2529
+ "name": "config",
2530
+ "pda": {
2531
+ "seeds": [
2532
+ {
2533
+ "kind": "const",
2534
+ "value": [
2535
+ 99,
2536
+ 111,
2537
+ 110,
2538
+ 102,
2539
+ 105,
2540
+ 103
2541
+ ]
2542
+ }
2543
+ ]
2544
+ }
2545
+ },
2546
+ {
2547
+ "name": "agent",
2548
+ "pda": {
2549
+ "seeds": [
2550
+ {
2551
+ "kind": "const",
2552
+ "value": [
2553
+ 97,
2554
+ 103,
2555
+ 101,
2556
+ 110,
2557
+ 116
2558
+ ]
2559
+ },
2560
+ {
2561
+ "kind": "arg",
2562
+ "path": "agent_id"
2563
+ }
2564
+ ]
2565
+ }
2566
+ },
2567
+ {
2568
+ "name": "twitter",
2569
+ "writable": true,
2570
+ "pda": {
2571
+ "seeds": [
2572
+ {
2573
+ "kind": "const",
2574
+ "value": [
2575
+ 116,
2576
+ 119,
2577
+ 105,
2578
+ 116,
2579
+ 116,
2580
+ 101,
2581
+ 114
2582
+ ]
2583
+ },
2584
+ {
2585
+ "kind": "account",
2586
+ "path": "agent"
2587
+ }
2588
+ ]
2589
+ }
2590
+ },
2591
+ {
2592
+ "name": "twitter_queue",
2593
+ "writable": true,
2594
+ "pda": {
2595
+ "seeds": [
2596
+ {
2597
+ "kind": "const",
2598
+ "value": [
2599
+ 116,
2600
+ 119,
2601
+ 105,
2602
+ 116,
2603
+ 116,
2604
+ 101,
2605
+ 114,
2606
+ 95,
2607
+ 113,
2608
+ 117,
2609
+ 101,
2610
+ 117,
2611
+ 101
2612
+ ]
2613
+ }
2614
+ ]
2615
+ }
2616
+ },
2617
+ {
2618
+ "name": "system_program",
2619
+ "address": "11111111111111111111111111111111"
2620
+ }
2621
+ ],
2622
+ "args": [
2623
+ {
2624
+ "name": "agent_id",
2625
+ "type": "string"
2626
+ },
2627
+ {
2628
+ "name": "reason",
2629
+ "type": "u64"
2630
+ }
2631
+ ]
2632
+ },
2510
2633
  {
2511
2634
  "name": "set_bio",
2512
2635
  "discriminator": [
@@ -4933,12 +5056,25 @@
4933
5056
  ]
4934
5057
  }
4935
5058
  },
5059
+ {
5060
+ "name": "rejection_reason",
5061
+ "type": "u64"
5062
+ },
4936
5063
  {
4937
5064
  "name": "_reserved",
4938
5065
  "type": {
4939
5066
  "array": [
4940
5067
  "u8",
4941
- 128
5068
+ 96
5069
+ ]
5070
+ }
5071
+ },
5072
+ {
5073
+ "name": "_reserved_a",
5074
+ "type": {
5075
+ "array": [
5076
+ "u8",
5077
+ 24
4942
5078
  ]
4943
5079
  }
4944
5080
  },
@@ -2513,6 +2513,129 @@ export type NaraAgentRegistry = {
2513
2513
  }
2514
2514
  ]
2515
2515
  },
2516
+ {
2517
+ "name": "rejectTwitterWithReason",
2518
+ "discriminator": [
2519
+ 3,
2520
+ 212,
2521
+ 79,
2522
+ 37,
2523
+ 41,
2524
+ 111,
2525
+ 209,
2526
+ 83
2527
+ ],
2528
+ "accounts": [
2529
+ {
2530
+ "name": "verifier",
2531
+ "writable": true,
2532
+ "signer": true
2533
+ },
2534
+ {
2535
+ "name": "config",
2536
+ "pda": {
2537
+ "seeds": [
2538
+ {
2539
+ "kind": "const",
2540
+ "value": [
2541
+ 99,
2542
+ 111,
2543
+ 110,
2544
+ 102,
2545
+ 105,
2546
+ 103
2547
+ ]
2548
+ }
2549
+ ]
2550
+ }
2551
+ },
2552
+ {
2553
+ "name": "agent",
2554
+ "pda": {
2555
+ "seeds": [
2556
+ {
2557
+ "kind": "const",
2558
+ "value": [
2559
+ 97,
2560
+ 103,
2561
+ 101,
2562
+ 110,
2563
+ 116
2564
+ ]
2565
+ },
2566
+ {
2567
+ "kind": "arg",
2568
+ "path": "agentId"
2569
+ }
2570
+ ]
2571
+ }
2572
+ },
2573
+ {
2574
+ "name": "twitter",
2575
+ "writable": true,
2576
+ "pda": {
2577
+ "seeds": [
2578
+ {
2579
+ "kind": "const",
2580
+ "value": [
2581
+ 116,
2582
+ 119,
2583
+ 105,
2584
+ 116,
2585
+ 116,
2586
+ 101,
2587
+ 114
2588
+ ]
2589
+ },
2590
+ {
2591
+ "kind": "account",
2592
+ "path": "agent"
2593
+ }
2594
+ ]
2595
+ }
2596
+ },
2597
+ {
2598
+ "name": "twitterQueue",
2599
+ "writable": true,
2600
+ "pda": {
2601
+ "seeds": [
2602
+ {
2603
+ "kind": "const",
2604
+ "value": [
2605
+ 116,
2606
+ 119,
2607
+ 105,
2608
+ 116,
2609
+ 116,
2610
+ 101,
2611
+ 114,
2612
+ 95,
2613
+ 113,
2614
+ 117,
2615
+ 101,
2616
+ 117,
2617
+ 101
2618
+ ]
2619
+ }
2620
+ ]
2621
+ }
2622
+ },
2623
+ {
2624
+ "name": "systemProgram",
2625
+ "address": "11111111111111111111111111111111"
2626
+ }
2627
+ ],
2628
+ "args": [
2629
+ {
2630
+ "name": "agentId",
2631
+ "type": "string"
2632
+ },
2633
+ {
2634
+ "name": "reason",
2635
+ "type": "u64"
2636
+ }
2637
+ ]
2638
+ },
2516
2639
  {
2517
2640
  "name": "setBio",
2518
2641
  "discriminator": [
@@ -4939,12 +5062,25 @@ export type NaraAgentRegistry = {
4939
5062
  ]
4940
5063
  }
4941
5064
  },
5065
+ {
5066
+ "name": "rejectionReason",
5067
+ "type": "u64"
5068
+ },
4942
5069
  {
4943
5070
  "name": "reserved",
4944
5071
  "type": {
4945
5072
  "array": [
4946
5073
  "u8",
4947
- 128
5074
+ 96
5075
+ ]
5076
+ }
5077
+ },
5078
+ {
5079
+ "name": "reservedA",
5080
+ "type": {
5081
+ "array": [
5082
+ "u8",
5083
+ 24
4948
5084
  ]
4949
5085
  }
4950
5086
  },
package/src/quest.ts CHANGED
@@ -435,13 +435,20 @@ export async function submitAnswer(
435
435
  if (options.stake === "auto") {
436
436
  const quest = await getQuestInfo(connection, wallet, options);
437
437
  const stakeInfo = await getStakeInfo(connection, wallet.publicKey, options);
438
- const required = quest.effectiveStakeRequirement;
439
- const current = stakeInfo?.amount ?? 0;
440
- const deficit = required - current;
441
- if (deficit > 0) {
442
- stakeLamports = new BN(Math.round(deficit * LAMPORTS_PER_SOL));
443
- } else {
438
+ const freeCredits = stakeInfo?.freeCredits ?? 0;
439
+
440
+ if (freeCredits > 0) {
441
+ // 本轮使用免质押额度,不需要补质押
444
442
  stakeLamports = new BN(0);
443
+ } else {
444
+ const required = quest.effectiveStakeRequirement;
445
+ const current = stakeInfo?.amount ?? 0;
446
+ const deficit = required - current;
447
+ if (deficit > 0) {
448
+ stakeLamports = new BN(Math.round(deficit * LAMPORTS_PER_SOL));
449
+ } else {
450
+ stakeLamports = new BN(0);
451
+ }
445
452
  }
446
453
  } else {
447
454
  stakeLamports = new BN(Math.round(options.stake * LAMPORTS_PER_SOL));