movementkit-cli 1.0.15 → 1.0.16

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/dist/index.js CHANGED
@@ -2912,7 +2912,7 @@ var cac = (name = "") => new CAC(name);
2912
2912
  // src/index.ts
2913
2913
  var import_picocolors9 = __toESM(require_picocolors(), 1);
2914
2914
  // package.json
2915
- var version = "1.0.15";
2915
+ var version = "1.0.16";
2916
2916
 
2917
2917
  // node_modules/@clack/core/dist/index.mjs
2918
2918
  var import_sisteransi = __toESM(require_src(), 1);
@@ -72,6 +72,34 @@ movement move publish --url https://full.testnet.movementinfra.xyz/v1 --named-ad
72
72
 
73
73
  **IMPORTANT:** Always run `movement init` first to set up your account before compiling.
74
74
 
75
+ ## Project Structure (Multi-Module)
76
+
77
+ For complex DeFi applications, organize modules by concern:
78
+ ```
79
+ my_project/
80
+ ├── sources/
81
+ │ ├── errors.move # Shared error codes (base layer)
82
+ │ ├── math.move # Math utilities (depends on errors)
83
+ │ ├── token.move # Token/LP token (depends on math)
84
+ │ ├── pool.move # Core logic (depends on token)
85
+ │ └── factory.move # Registry (depends on pool)
86
+ ├── Move.toml
87
+ └── scripts/ # Optional deployment scripts
88
+ ```
89
+
90
+ **Module Dependency Hierarchy:**
91
+ ```
92
+ errors.move (base - no dependencies)
93
+
94
+ math.move (utilities)
95
+
96
+ token.move (LP token management)
97
+
98
+ pool.move (core AMM/DeFi logic)
99
+
100
+ factory.move (pool registry)
101
+ ```
102
+
75
103
  ## Move.toml Configuration
76
104
 
77
105
  ```toml
@@ -419,33 +447,139 @@ public fun get_count(addr: address): u64 acquires Counter {
419
447
  }
420
448
  ```
421
449
 
422
- ### Token/NFT Collection Pattern
450
+ ### Fungible Asset (Token) Pattern
423
451
  ```move
424
- struct Collection has key {
425
- items: vector<Item>,
426
- next_id: u64,
452
+ module module_addr::my_token {
453
+ use std::string;
454
+ use std::option;
455
+ use aptos_framework::object;
456
+ use aptos_framework::fungible_asset::{Self, MintRef, BurnRef, TransferRef};
457
+ use aptos_framework::primary_fungible_store;
458
+
459
+ const ASSET_SYMBOL: vector<u8> = b"MYTOKEN";
460
+
461
+ struct Management has key {
462
+ mint_ref: MintRef,
463
+ burn_ref: BurnRef,
464
+ transfer_ref: TransferRef,
465
+ }
466
+
467
+ fun init_module(admin: &signer) {
468
+ let constructor_ref = &object::create_named_object(admin, ASSET_SYMBOL);
469
+
470
+ primary_fungible_store::create_primary_store_enabled_fungible_asset(
471
+ constructor_ref,
472
+ option::none(), // max supply (none = unlimited)
473
+ string::utf8(b"My Token"),
474
+ string::utf8(ASSET_SYMBOL),
475
+ 8, // decimals
476
+ string::utf8(b"https://example.com/icon.png"),
477
+ string::utf8(b"https://example.com"),
478
+ );
479
+
480
+ let mint_ref = fungible_asset::generate_mint_ref(constructor_ref);
481
+ let burn_ref = fungible_asset::generate_burn_ref(constructor_ref);
482
+ let transfer_ref = fungible_asset::generate_transfer_ref(constructor_ref);
483
+
484
+ move_to(admin, Management { mint_ref, burn_ref, transfer_ref });
485
+ }
486
+
487
+ public entry fun mint(admin: &signer, to: address, amount: u64) acquires Management {
488
+ let management = borrow_global<Management>(@module_addr);
489
+ let tokens = fungible_asset::mint(&management.mint_ref, amount);
490
+ primary_fungible_store::deposit(to, tokens);
491
+ }
427
492
  }
493
+ ```
494
+
495
+ ### AMM Pool Pattern (Uniswap V2 Style)
496
+ ```move
497
+ module module_addr::pool {
498
+ use aptos_framework::coin::{Self, Coin};
499
+
500
+ struct LiquidityPool<phantom X, phantom Y> has key {
501
+ reserve_x: Coin<X>,
502
+ reserve_y: Coin<Y>,
503
+ total_lp_supply: u64,
504
+ }
428
505
 
429
- struct Item has store, drop {
430
- id: u64,
431
- name: String,
432
- owner: address,
506
+ /// Constant product formula: x * y = k
507
+ public fun get_amount_out(amount_in: u64, reserve_in: u64, reserve_out: u64): u64 {
508
+ let amount_in_with_fee = (amount_in as u128) * 997; // 0.3% fee
509
+ let numerator = amount_in_with_fee * (reserve_out as u128);
510
+ let denominator = ((reserve_in as u128) * 1000) + amount_in_with_fee;
511
+ ((numerator / denominator) as u64)
512
+ }
513
+
514
+ /// Safe math: multiply then divide using u128 to prevent overflow
515
+ public fun safe_mul_div(a: u64, b: u64, c: u64): u64 {
516
+ assert!(c > 0, 1); // E_DIVISION_BY_ZERO
517
+ let result = ((a as u128) * (b as u128)) / (c as u128);
518
+ (result as u64)
519
+ }
433
520
  }
521
+ ```
434
522
 
435
- public entry fun mint(account: &signer, name: String) acquires Collection {
436
- let addr = signer::address_of(account);
437
- let collection = borrow_global_mut<Collection>(@module_addr);
523
+ ### Collateral Position Pattern (DeFi)
524
+ ```move
525
+ module module_addr::vault {
526
+ const MIN_COLLATERAL_RATIO: u64 = 15000; // 150% in basis points
527
+ const BASIS_POINTS: u64 = 10000;
438
528
 
439
- let item = Item {
440
- id: collection.next_id,
441
- name,
442
- owner: addr,
443
- };
529
+ struct CollateralPosition has key {
530
+ collateral_amount: u64,
531
+ minted_amount: u64,
532
+ }
533
+
534
+ fun is_position_healthy(collateral: u64, minted: u64, price: u64): bool {
535
+ if (minted == 0) return true;
536
+ let collateral_value = collateral * price;
537
+ let required = (minted * MIN_COLLATERAL_RATIO) / BASIS_POINTS;
538
+ collateral_value >= required
539
+ }
444
540
 
445
- vector::push_back(&mut collection.items, item);
446
- collection.next_id = collection.next_id + 1;
541
+ public entry fun deposit_and_mint(
542
+ user: &signer,
543
+ collateral_amount: u64,
544
+ mint_amount: u64
545
+ ) acquires CollateralPosition {
546
+ // Validate position remains healthy after mint
547
+ assert!(is_position_healthy(collateral_amount, mint_amount, get_price()), E_UNDERCOLLATERALIZED);
548
+ // ... deposit collateral and mint tokens
549
+ }
550
+ }
551
+ ```
552
+
553
+ ### Math Utilities Module
554
+ ```move
555
+ module module_addr::math {
556
+ const E_DIVIDE_BY_ZERO: u64 = 100;
557
+ const E_OVERFLOW: u64 = 101;
558
+
559
+ /// Safe multiply then divide using u256 to prevent overflow
560
+ public fun mul_div(a: u64, b: u64, c: u64): u64 {
561
+ assert!(c > 0, E_DIVIDE_BY_ZERO);
562
+ let result = ((a as u256) * (b as u256)) / (c as u256);
563
+ assert!(result <= 18446744073709551615, E_OVERFLOW); // u64 max
564
+ (result as u64)
565
+ }
447
566
 
448
- event::emit(ItemMinted { id: collection.next_id - 1, owner: addr });
567
+ /// Square root using Newton's method (for LP token calculation)
568
+ public fun sqrt(x: u128): u128 {
569
+ if (x == 0) return 0;
570
+ let z = (x + 1) / 2;
571
+ let y = x;
572
+ while (z < y) {
573
+ y = z;
574
+ z = (x / z + z) / 2;
575
+ };
576
+ y
577
+ }
578
+
579
+ /// Calculate minimum of two values
580
+ public fun min(a: u64, b: u64): u64 {
581
+ if (a < b) a else b
582
+ }
449
583
  }
450
584
  ```
451
585
 
@@ -458,6 +592,8 @@ public entry fun mint(account: &signer, name: String) acquires Collection {
458
592
  5. **Avoid unbounded loops** - Can cause out-of-gas errors
459
593
  6. **Use acquires annotation** - Declare all resources accessed
460
594
  7. **Initialize before use** - Ensure resources exist before borrowing
595
+ 8. **Use u128/u256 for intermediate math** - Prevent overflow in calculations
596
+ 9. **Validate collateral ratios** - Always check positions remain healthy
461
597
 
462
598
  ## Complete Example: Simple Token
463
599
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "movementkit-cli",
3
- "version": "1.0.15",
3
+ "version": "1.0.16",
4
4
  "description": "CLI tool for bootstrapping and updating Movement Kit projects for Movement blockchain development",
5
5
  "type": "module",
6
6
  "repository": {