diff --git a/.changeset/late-dancers-rush.md b/.changeset/late-dancers-rush.md new file mode 100644 index 0000000000000..ffaef2ac02677 --- /dev/null +++ b/.changeset/late-dancers-rush.md @@ -0,0 +1,5 @@ +--- +'@mysten/sui': patch +--- + +Add tx.object.option for creatnig object options in transaction builder diff --git a/crates/sui-core/src/unit_tests/data/entry_point_types/Move.lock b/crates/sui-core/src/unit_tests/data/entry_point_types/Move.lock index d637193357491..a3fcd9c1ec33f 100644 --- a/crates/sui-core/src/unit_tests/data/entry_point_types/Move.lock +++ b/crates/sui-core/src/unit_tests/data/entry_point_types/Move.lock @@ -1,27 +1,27 @@ # @generated by Move, please check-in and do not edit manually. [move] -version = 0 +version = 3 manifest_digest = "84B1ECECEB235E605B786F20F7F6441F45D0E087391F555801F49504C491BECE" deps_digest = "F8BBB0CCB2491CA29A3DF03D6F92277A4F3574266507ACD77214D37ECA3F3082" dependencies = [ - { name = "Sui" }, + { id = "Sui", name = "Sui" }, ] [[move.package]] -name = "MoveStdlib" +id = "MoveStdlib" source = { local = "../../../../../sui-framework/packages/move-stdlib" } [[move.package]] -name = "Sui" +id = "Sui" source = { local = "../../../../../sui-framework/packages/sui-framework" } dependencies = [ - { name = "MoveStdlib" }, + { id = "MoveStdlib", name = "MoveStdlib" }, ] [move.toolchain-version] -compiler-version = "1.30.0" +compiler-version = "1.38.0" edition = "2024.beta" flavor = "sui" diff --git a/crates/sui-core/src/unit_tests/data/entry_point_vector/Move.lock b/crates/sui-core/src/unit_tests/data/entry_point_vector/Move.lock index 6cca232fdf7a3..2e9051778ac64 100644 --- a/crates/sui-core/src/unit_tests/data/entry_point_vector/Move.lock +++ b/crates/sui-core/src/unit_tests/data/entry_point_vector/Move.lock @@ -1,27 +1,27 @@ # @generated by Move, please check-in and do not edit manually. [move] -version = 0 +version = 3 manifest_digest = "78784529799C8284788E91AB0A8668CA7759418A3D6133C3ADE575F648524A1E" deps_digest = "F8BBB0CCB2491CA29A3DF03D6F92277A4F3574266507ACD77214D37ECA3F3082" dependencies = [ - { name = "Sui" }, + { id = "Sui", name = "Sui" }, ] [[move.package]] -name = "MoveStdlib" +id = "MoveStdlib" source = { local = "../../../../../sui-framework/packages/move-stdlib" } [[move.package]] -name = "Sui" +id = "Sui" source = { local = "../../../../../sui-framework/packages/sui-framework" } dependencies = [ - { name = "MoveStdlib" }, + { id = "MoveStdlib", name = "MoveStdlib" }, ] [move.toolchain-version] -compiler-version = "1.30.0" +compiler-version = "1.38.0" edition = "2024.beta" flavor = "sui" diff --git a/sdk/docs/pages/typescript/transaction-building/basics.mdx b/sdk/docs/pages/typescript/transaction-building/basics.mdx index 12b0f8d767e4d..a0ce0099232ea 100644 --- a/sdk/docs/pages/typescript/transaction-building/basics.mdx +++ b/sdk/docs/pages/typescript/transaction-building/basics.mdx @@ -190,7 +190,7 @@ tx.moveCall({ arguments: [tx.object('0xSomeObject')], }); -// tx.object automaically converts the object ID to receiving transaction arguments if the moveCall expects it +// tx.object automatically converts the object ID to receiving transaction arguments if the moveCall expects it tx.moveCall({ target: '0xSomeAddress::example::receive_object', // 0xSomeAddress::example::receive_object expects a receiving argument and has a Move definition that looks like this: @@ -217,6 +217,24 @@ tx.object(Inputs.SharedObjectRef({ objectId, initialSharedVersion, mutable })); tx.object(Inputs.ReceivingRef({ digest, objectId, version })); ``` +##### Object helpers + +There are a handful of specific object types that can be referenced through helper methods on +tx.object: + +```ts +tx.object.system(), +tx.object.clock(), +tx.object.random(), +tx.object.denyList(), + +tx.object.option({ + type: '0x123::example::Thing', + // value can be an Object ID, or any other object reference, or null for `none` + value: '0x456', +}), +``` + #### Transaction results You can also use the result of a transaction as an argument in a subsequent transactions. Each diff --git a/sdk/typescript/package.json b/sdk/typescript/package.json index 760b955abb3cb..5d3daf664f397 100644 --- a/sdk/typescript/package.json +++ b/sdk/typescript/package.json @@ -102,7 +102,7 @@ "test:unit": "vitest run unit __tests__", "test:e2e": "wait-on http://127.0.0.1:9123 -l --timeout 180000 && vitest run e2e", "test:e2e:nowait": "vitest run e2e", - "prepare:e2e": "docker-compose down && docker-compose up -d && cargo build --bin sui --profile dev && cross-env RUST_LOG=warn,sui=error,anemo_tower=warn,consensus=off ../../target/debug/sui start --with-faucet --force-regenesis --with-indexer --pg-port 5435 --pg-db-name sui_indexer_v2 --with-graphql", + "prepare:e2e": "docker-compose down && docker-compose up -d && cargo build --bin sui --profile dev && cross-env RUST_LOG=warn,anemo_tower=warn,consensus=off ../../target/debug/sui start --with-faucet --force-regenesis --with-indexer --pg-port 5435 --pg-db-name sui_indexer_v2 --with-graphql", "prepublishOnly": "pnpm build", "size": "size-limit", "analyze": "size-limit --why", diff --git a/sdk/typescript/src/transactions/object.ts b/sdk/typescript/src/transactions/object.ts index ff83fac9dc750..e17fed5f1de21 100644 --- a/sdk/typescript/src/transactions/object.ts +++ b/sdk/typescript/src/transactions/object.ts @@ -1,7 +1,7 @@ // Copyright (c) Mysten Labs, Inc. // SPDX-License-Identifier: Apache-2.0 -import type { TransactionObjectInput } from './Transaction.js'; +import type { Transaction, TransactionObjectInput } from './Transaction.js'; export function createObjectMethods(makeObject: (value: TransactionObjectInput) => T) { function object(value: TransactionObjectInput) { @@ -12,6 +12,14 @@ export function createObjectMethods(makeObject: (value: TransactionObjectInpu object.clock = () => object('0x6'); object.random = () => object('0x8'); object.denyList = () => object('0x403'); + object.option = + ({ type, value }: { type: string; value: TransactionObjectInput | null }) => + (tx: Transaction) => + tx.moveCall({ + typeArguments: [type], + target: `0x1::option::${value === null ? 'none' : 'some'}`, + arguments: value === null ? [] : [tx.object(value)], + }); return object; } diff --git a/sdk/typescript/test/e2e/data/coin_metadata/Move.lock b/sdk/typescript/test/e2e/data/coin_metadata/Move.lock index ce2caf0923842..345facce46655 100644 --- a/sdk/typescript/test/e2e/data/coin_metadata/Move.lock +++ b/sdk/typescript/test/e2e/data/coin_metadata/Move.lock @@ -1,27 +1,27 @@ # @generated by Move, please check-in and do not edit manually. [move] -version = 0 +version = 3 manifest_digest = "AFCC8C08D078426D5FE98FB22E21578C4A7B9C1259C6EE53BEF2861BB801C976" deps_digest = "F8BBB0CCB2491CA29A3DF03D6F92277A4F3574266507ACD77214D37ECA3F3082" dependencies = [ - { name = "Sui" }, + { id = "Sui", name = "Sui" }, ] [[move.package]] -name = "MoveStdlib" +id = "MoveStdlib" source = { local = "../../../../../../crates/sui-framework/packages/move-stdlib" } [[move.package]] -name = "Sui" +id = "Sui" source = { local = "../../../../../../crates/sui-framework/packages/sui-framework" } dependencies = [ - { name = "MoveStdlib" }, + { id = "MoveStdlib", name = "MoveStdlib" }, ] [move.toolchain-version] -compiler-version = "1.30.0" +compiler-version = "1.38.0" edition = "2024.beta" flavor = "sui" diff --git a/sdk/typescript/test/e2e/data/coin_metadata/sources/coin_metadata.move b/sdk/typescript/test/e2e/data/coin_metadata/sources/coin_metadata.move index d547669973fd1..55ccde0a4f4a9 100644 --- a/sdk/typescript/test/e2e/data/coin_metadata/sources/coin_metadata.move +++ b/sdk/typescript/test/e2e/data/coin_metadata/sources/coin_metadata.move @@ -1,29 +1,37 @@ // Copyright (c) Mysten Labs, Inc. // SPDX-License-Identifier: Apache-2.0 -module coin_metadata::test { - use std::option; - use sui::coin; - use sui::transfer; - use sui::url; +module coin_metadata::test; - public struct TEST has drop {} +use sui::coin; +use sui::url; - fun init(witness: TEST, ctx: &mut TxContext) { - let (mut treasury_cap, metadata) = coin::create_currency( - witness, - 2, - b"TEST", - b"Test Coin", - b"Test coin metadata", - option::some(url::new_unsafe_from_bytes(b"http://sui.io")), - ctx - ); +public struct TEST has drop {} - coin::mint_and_transfer(&mut treasury_cap, 5, tx_context::sender(ctx), ctx); - coin::mint_and_transfer(&mut treasury_cap, 6, tx_context::sender(ctx), ctx); +fun init(witness: TEST, ctx: &mut TxContext) { + let (mut treasury_cap, metadata) = coin::create_currency( + witness, + 2, + b"TEST", + b"Test Coin", + b"Test coin metadata", + option::some(url::new_unsafe_from_bytes(b"http://sui.io")), + ctx, + ); - transfer::public_share_object(metadata); - transfer::public_share_object(treasury_cap) - } + coin::mint_and_transfer( + &mut treasury_cap, + 5, + tx_context::sender(ctx), + ctx, + ); + coin::mint_and_transfer( + &mut treasury_cap, + 6, + tx_context::sender(ctx), + ctx, + ); + + transfer::public_share_object(metadata); + transfer::public_share_object(treasury_cap) } diff --git a/sdk/typescript/test/e2e/data/demo-bear/sources/demo_bear.move b/sdk/typescript/test/e2e/data/demo-bear/sources/demo_bear.move index 1f45573ac32b0..a52b3ef009d89 100644 --- a/sdk/typescript/test/e2e/data/demo-bear/sources/demo_bear.move +++ b/sdk/typescript/test/e2e/data/demo-bear/sources/demo_bear.move @@ -1,58 +1,57 @@ // Copyright (c) Mysten Labs, Inc. // SPDX-License-Identifier: Apache-2.0 -module demo::demo_bear { - use std::string::{String, utf8}; +module demo::demo_bear; - use sui::package; - use sui::display; +use std::string::{String, utf8}; +use sui::display; +use sui::package; - /// our demo struct. - public struct DemoBear has key, store { - id: UID, - name: String - } +/// our demo struct. +public struct DemoBear has key, store { + id: UID, + name: String, +} - /// our OTW to create display. - public struct DEMO_BEAR has drop {} - - // It's recommened to create Display using PTBs instead of - // directly on the contracts. - // We are only creating it here for demo purposes (one-step setup). - fun init(otw: DEMO_BEAR, ctx: &mut TxContext){ - let publisher = package::claim(otw, ctx); - let keys = vector[ - utf8(b"name"), - utf8(b"image_url"), - utf8(b"description"), - ]; - - - let values = vector[ - // Let's add a demo name for our `DemoBear` - utf8(b"{name}"), - // Adding a happy bear image. - utf8(b"https://images.unsplash.com/photo-1589656966895-2f33e7653819?q=80&w=1000&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxzZWFyY2h8Mnx8cG9sYXIlMjBiZWFyfGVufDB8fDB8fHww"), - // Description is static for all bears out there. - utf8(b"The greatest figure for demos"), - ]; - - // Get a new `Display` object for the `Hero` type. - let mut display = display::new_with_fields( - &publisher, keys, values, ctx - ); - - // Commit first version of `Display` to apply changes. - display::update_version(&mut display); - - sui::transfer::public_transfer(display, ctx.sender()); - sui::transfer::public_transfer(publisher, ctx.sender()) - } +/// our OTW to create display. +public struct DEMO_BEAR has drop {} + +// It's recommened to create Display using PTBs instead of +// directly on the contracts. +// We are only creating it here for demo purposes (one-step setup). +fun init(otw: DEMO_BEAR, ctx: &mut TxContext) { + let publisher = package::claim(otw, ctx); + let keys = vector[utf8(b"name"), utf8(b"image_url"), utf8(b"description")]; + + let values = vector[ + // Let's add a demo name for our `DemoBear` + utf8(b"{name}"), + // Adding a happy bear image. + utf8( + b"https://images.unsplash.com/photo-1589656966895-2f33e7653819?q=80&w=1000&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxzZWFyY2h8Mnx8cG9sYXIlMjBiZWFyfGVufDB8fDB8fHww", + ), + // Description is static for all bears out there. + utf8(b"The greatest figure for demos"), + ]; + + // Get a new `Display` object for the `Hero` type. + let mut display = display::new_with_fields( + &publisher, + keys, + values, + ctx, + ); + + // Commit first version of `Display` to apply changes. + display::update_version(&mut display); + + sui::transfer::public_transfer(display, ctx.sender()); + sui::transfer::public_transfer(publisher, ctx.sender()) +} - public fun new(name: String, ctx: &mut TxContext): DemoBear { - DemoBear { - id: object::new(ctx), - name: name - } +public fun new(name: String, ctx: &mut TxContext): DemoBear { + DemoBear { + id: object::new(ctx), + name: name, } } diff --git a/sdk/typescript/test/e2e/data/display_test/sources/display_test.move b/sdk/typescript/test/e2e/data/display_test/sources/display_test.move index ef097c0c3aeea..f14a580a11364 100644 --- a/sdk/typescript/test/e2e/data/display_test/sources/display_test.move +++ b/sdk/typescript/test/e2e/data/display_test/sources/display_test.move @@ -1,43 +1,45 @@ // Copyright (c) Mysten Labs, Inc. // SPDX-License-Identifier: Apache-2.0 -module display_test::boars { - use sui::tx_context::{sender}; - use sui::transfer; - use sui::package; - use sui::url::{Self, Url}; - use sui::display; - use std::string::{utf8, String}; +module display_test::boars; - /// For when a witness type passed is not an OTW. - const ENotOneTimeWitness: u64 = 0; +use std::string::{utf8, String}; +use sui::display; +use sui::package; +use sui::tx_context::sender; +use sui::url::{Self, Url}; - /// An OTW to use when creating a Publisher - public struct BOARS has drop {} +/// For when a witness type passed is not an OTW. +const ENotOneTimeWitness: u64 = 0; - public struct Boar has key, store { - id: UID, - img_url: String, - name: String, - description: String, - creator: Option, - price: Option, - metadata: Metadata, - buyer: address, - full_url: Url, - } +/// An OTW to use when creating a Publisher +public struct BOARS has drop {} - public struct Metadata has store { - age: u64, - } +public struct Boar has key, store { + id: UID, + img_url: String, + name: String, + description: String, + creator: Option, + price: Option, + metadata: Metadata, + buyer: address, + full_url: Url, +} + +public struct Metadata has store { + age: u64, +} - fun init(otw: BOARS, ctx: &mut TxContext) { - assert!(sui::types::is_one_time_witness(&otw), ENotOneTimeWitness); +fun init(otw: BOARS, ctx: &mut TxContext) { + assert!(sui::types::is_one_time_witness(&otw), ENotOneTimeWitness); - let pub = package::claim(otw, ctx); - let mut display = display::new(&pub, ctx); + let pub = package::claim(otw, ctx); + let mut display = display::new(&pub, ctx); - display::add_multiple(&mut display, vector[ + display::add_multiple( + &mut display, + vector[ utf8(b"name"), utf8(b"description"), utf8(b"img_url"), @@ -50,48 +52,41 @@ module display_test::boars { utf8(b"escape_syntax"), utf8(b"id"), utf8(b"bad_name"), - ], vector[ + ], + vector[ utf8(b"{name}"), - // test multiple fields and UID utf8(b"Unique Boar from the Boars collection with {name} and {id}"), utf8(b"https://get-a-boar.com/{img_url}"), - // test option::some utf8(b"{creator}"), - // test option::none utf8(b"{price}"), - // test no template value utf8(b"https://get-a-boar.com/"), - // test nested field utf8(b"{metadata.age}"), - // test address utf8(b"{buyer}"), - // test Url type utf8(b"{full_url}"), - // test escape syntax utf8(b"\\{name\\}"), - // bad id utf8(b"{idd}"), - // Bad name - utf8(b"{namee}") - ]); + utf8(b"{namee}"), + ], + ); - display::update_version(&mut display); - transfer::public_transfer(display, sender(ctx)); - transfer::public_transfer(pub, sender(ctx)); + display::update_version(&mut display); + transfer::public_transfer(display, sender(ctx)); + transfer::public_transfer(pub, sender(ctx)); - let boar = Boar { - id: object::new(ctx), - img_url: utf8(b"first.png"), - name: utf8(b"First Boar"), - description: utf8(b"First Boar from the Boars collection!"), - creator: option::some(utf8(b"Chris")), - price: option::none(), - metadata: Metadata { - age: 10, - }, - buyer: sender(ctx), - full_url: url::new_unsafe_from_bytes(b"https://get-a-boar.fullurl.com/"), - }; - transfer::transfer(boar, sender(ctx)) - } + let boar = Boar { + id: object::new(ctx), + img_url: utf8(b"first.png"), + name: utf8(b"First Boar"), + description: utf8(b"First Boar from the Boars collection!"), + creator: option::some(utf8(b"Chris")), + price: option::none(), + metadata: Metadata { + age: 10, + }, + buyer: sender(ctx), + full_url: url::new_unsafe_from_bytes( + b"https://get-a-boar.fullurl.com/", + ), + }; + transfer::transfer(boar, sender(ctx)) } diff --git a/sdk/typescript/test/e2e/data/dynamic_fields/Move.lock b/sdk/typescript/test/e2e/data/dynamic_fields/Move.lock index 438df7255bad1..de346af015fae 100644 --- a/sdk/typescript/test/e2e/data/dynamic_fields/Move.lock +++ b/sdk/typescript/test/e2e/data/dynamic_fields/Move.lock @@ -1,27 +1,27 @@ # @generated by Move, please check-in and do not edit manually. [move] -version = 0 +version = 3 manifest_digest = "76911963FC697963763F7C39BA84E5245E996BA8C115F84B1497343F33103988" deps_digest = "F8BBB0CCB2491CA29A3DF03D6F92277A4F3574266507ACD77214D37ECA3F3082" dependencies = [ - { name = "Sui" }, + { id = "Sui", name = "Sui" }, ] [[move.package]] -name = "MoveStdlib" +id = "MoveStdlib" source = { local = "../../../../../../crates/sui-framework/packages/move-stdlib" } [[move.package]] -name = "Sui" +id = "Sui" source = { local = "../../../../../../crates/sui-framework/packages/sui-framework" } dependencies = [ - { name = "MoveStdlib" }, + { id = "MoveStdlib", name = "MoveStdlib" }, ] [move.toolchain-version] -compiler-version = "1.30.0" +compiler-version = "1.38.0" edition = "2024.beta" flavor = "sui" diff --git a/sdk/typescript/test/e2e/data/dynamic_fields/sources/dynamic_fields.move b/sdk/typescript/test/e2e/data/dynamic_fields/sources/dynamic_fields.move index 9bb36e35bbcd0..f08df6f8cb0f4 100644 --- a/sdk/typescript/test/e2e/data/dynamic_fields/sources/dynamic_fields.move +++ b/sdk/typescript/test/e2e/data/dynamic_fields/sources/dynamic_fields.move @@ -1,40 +1,39 @@ // Copyright (c) Mysten Labs, Inc. // SPDX-License-Identifier: Apache-2.0 -module dynamic_fields::dynamic_fields_test { - use sui::dynamic_field as dfield; - use sui::dynamic_object_field as dof; - use sui::transfer; +module dynamic_fields::dynamic_fields_test; - public struct Test has key { - id: UID, - } +use sui::dynamic_field as dfield; +use sui::dynamic_object_field as dof; - public struct Test1 has key, store { - id: UID, - } +public struct Test has key { + id: UID, +} + +public struct Test1 has key, store { + id: UID, +} - public struct Test2 has key, store { - id: UID, - } +public struct Test2 has key, store { + id: UID, +} - fun init(ctx: &mut TxContext) { - let mut test = Test{ - id: object::new(ctx), - }; +fun init(ctx: &mut TxContext) { + let mut test = Test { + id: object::new(ctx), + }; - let test1 = Test1{ - id: object::new(ctx) - }; + let test1 = Test1 { + id: object::new(ctx), + }; - let test2 = Test2{ - id: object::new(ctx) - }; + let test2 = Test2 { + id: object::new(ctx), + }; - dfield::add(&mut test.id, object::id(&test1), test1); + dfield::add(&mut test.id, object::id(&test1), test1); - dof::add(&mut test.id, object::id(&test2), test2); + dof::add(&mut test.id, object::id(&test2), test2); - transfer::transfer(test, tx_context::sender(ctx)) - } + transfer::transfer(test, tx_context::sender(ctx)) } diff --git a/sdk/typescript/test/e2e/data/id_entry_args/Move.lock b/sdk/typescript/test/e2e/data/id_entry_args/Move.lock index 04c8672f54a02..48498a46386b7 100644 --- a/sdk/typescript/test/e2e/data/id_entry_args/Move.lock +++ b/sdk/typescript/test/e2e/data/id_entry_args/Move.lock @@ -1,27 +1,27 @@ # @generated by Move, please check-in and do not edit manually. [move] -version = 0 +version = 3 manifest_digest = "20F8CB8FCA34CA6BF6F1483557408766EF8F8821F095D92B02E63B5146852526" deps_digest = "F8BBB0CCB2491CA29A3DF03D6F92277A4F3574266507ACD77214D37ECA3F3082" dependencies = [ - { name = "Sui" }, + { id = "Sui", name = "Sui" }, ] [[move.package]] -name = "MoveStdlib" +id = "MoveStdlib" source = { local = "../../../../../../crates/sui-framework/packages/move-stdlib" } [[move.package]] -name = "Sui" +id = "Sui" source = { local = "../../../../../../crates/sui-framework/packages/sui-framework" } dependencies = [ - { name = "MoveStdlib" }, + { id = "MoveStdlib", name = "MoveStdlib" }, ] [move.toolchain-version] -compiler-version = "1.30.0" +compiler-version = "1.38.0" edition = "2024.beta" flavor = "sui" diff --git a/sdk/typescript/test/e2e/data/id_entry_args/sources/id_entry_args.move b/sdk/typescript/test/e2e/data/id_entry_args/sources/id_entry_args.move index 8c5f2c2c923e1..b6547925112dd 100644 --- a/sdk/typescript/test/e2e/data/id_entry_args/sources/id_entry_args.move +++ b/sdk/typescript/test/e2e/data/id_entry_args/sources/id_entry_args.move @@ -1,12 +1,18 @@ // Copyright (c) Mysten Labs, Inc. // SPDX-License-Identifier: Apache-2.0 -module id_entry_args::test { - public entry fun test_id(id: ID, _ctx: &mut TxContext) { - assert!(object::id_to_address(&id) == @0xc2b5625c221264078310a084df0a3137956d20ee, 0); - } +module id_entry_args::test; - public entry fun test_id_non_mut(id: ID, _ctx: &TxContext) { - assert!(object::id_to_address(&id) == @0xc2b5625c221264078310a084df0a3137956d20ee, 0); - } +public entry fun test_id(id: ID, _ctx: &mut TxContext) { + assert!( + object::id_to_address(&id) == @0xc2b5625c221264078310a084df0a3137956d20ee, + 0, + ); +} + +public entry fun test_id_non_mut(id: ID, _ctx: &TxContext) { + assert!( + object::id_to_address(&id) == @0xc2b5625c221264078310a084df0a3137956d20ee, + 0, + ); } diff --git a/sdk/typescript/test/e2e/data/serializer/Move.lock b/sdk/typescript/test/e2e/data/serializer/Move.lock index 0da12b5b3f133..b423d605853fd 100644 --- a/sdk/typescript/test/e2e/data/serializer/Move.lock +++ b/sdk/typescript/test/e2e/data/serializer/Move.lock @@ -1,27 +1,27 @@ # @generated by Move, please check-in and do not edit manually. [move] -version = 0 +version = 3 manifest_digest = "8C8B9ADAFF8B7267E4476A3DF08A72810194D36146AC710F0545C8843B1F1075" deps_digest = "F8BBB0CCB2491CA29A3DF03D6F92277A4F3574266507ACD77214D37ECA3F3082" dependencies = [ - { name = "Sui" }, + { id = "Sui", name = "Sui" }, ] [[move.package]] -name = "MoveStdlib" +id = "MoveStdlib" source = { local = "../../../../../../crates/sui-framework/packages/move-stdlib" } [[move.package]] -name = "Sui" +id = "Sui" source = { local = "../../../../../../crates/sui-framework/packages/sui-framework" } dependencies = [ - { name = "MoveStdlib" }, + { id = "MoveStdlib", name = "MoveStdlib" }, ] [move.toolchain-version] -compiler-version = "1.30.0" +compiler-version = "1.38.0" edition = "2024.beta" flavor = "sui" diff --git a/sdk/typescript/test/e2e/data/serializer/sources/serializer.move b/sdk/typescript/test/e2e/data/serializer/sources/serializer.move index d990ce1ac5bef..197529d080683 100644 --- a/sdk/typescript/test/e2e/data/serializer/sources/serializer.move +++ b/sdk/typescript/test/e2e/data/serializer/sources/serializer.move @@ -1,66 +1,78 @@ // Copyright (c) Mysten Labs, Inc. // SPDX-License-Identifier: Apache-2.0 -module serializer::serializer_tests { - use sui::clock::Clock; - use std::option::Option; - use sui::object::ID; - use std::string::String; - use std::ascii; - - public struct MutableShared has key { - id: UID, - value: u64, - } - - fun init(ctx: &mut TxContext) { - transfer::share_object(MutableShared { - id: object::new(ctx), - value: 1, - }) - } - - public entry fun use_clock(_clock: &Clock) {} - - public entry fun list( - item: T, - ctx: &mut TxContext - ) { - transfer::public_transfer(item, tx_context::sender(ctx)) - } - - public fun return_struct( - item: T, - ): T { - item - } - - public entry fun value(clock: &MutableShared) { - assert!(clock.value > 0, 1); - } - - public entry fun set_value(clock: &mut MutableShared) { - clock.value = 10; - } - - public entry fun delete_value(clock: MutableShared) { - let MutableShared { id, value: _ } = clock; - object::delete(id); - } - - public fun test_abort() { - abort 0 - } - - public fun addr(_: address) {} - public fun id(_: ID) {} - - public fun ascii_(_: ascii::String) {} - public fun string(_: String) {} - - public fun vec(_: vector) {} - public fun opt(_: Option) {} - - public fun ints(_u8: u8, _u16: u16, _u32: u32, _u64: u64, _u128: u128, _u256: u256) {} - public fun boolean(_bool: bool) {} +module serializer::serializer_tests; + +use std::ascii; +use std::string::String; +use sui::clock::Clock; + +public struct MutableShared has key { + id: UID, + value: u64, +} + +fun init(ctx: &mut TxContext) { + transfer::share_object(MutableShared { + id: object::new(ctx), + value: 1, + }) +} + +public entry fun use_clock(_clock: &Clock) {} + +public entry fun list(item: T, ctx: &mut TxContext) { + transfer::public_transfer(item, tx_context::sender(ctx)) +} + +public fun return_struct(item: T): T { + item +} + +public entry fun value(clock: &MutableShared) { + assert!(clock.value > 0, 1); +} + +public entry fun set_value(clock: &mut MutableShared) { + clock.value = 10; +} + +public entry fun delete_value(clock: MutableShared) { + let MutableShared { id, value: _ } = clock; + object::delete(id); +} + +public fun test_abort() { + abort 0 +} + +public fun addr(_: address) {} + +public fun id(_: ID) {} + +public fun ascii_(_: ascii::String) {} + +public fun string(_: String) {} + +public fun vec(_: vector) {} + +public fun opt(_: Option) {} + +public fun ints( + _u8: u8, + _u16: u16, + _u32: u32, + _u64: u64, + _u128: u128, + _u256: u256, +) {} + +public fun boolean(_bool: bool) {} + +public fun some(opt: Option): T { + opt.destroy_some() +} + +public fun none(opt: Option) { + opt.destroy_none() } diff --git a/sdk/typescript/test/e2e/data/serializer_upgrade/sources/serializer.move b/sdk/typescript/test/e2e/data/serializer_upgrade/sources/serializer.move index cf34cd3659f08..c0f3fbec02784 100644 --- a/sdk/typescript/test/e2e/data/serializer_upgrade/sources/serializer.move +++ b/sdk/typescript/test/e2e/data/serializer_upgrade/sources/serializer.move @@ -1,66 +1,78 @@ // Copyright (c) Mysten Labs, Inc. // SPDX-License-Identifier: Apache-2.0 -module serializer::serializer_tests { - use sui::transfer; - use sui::clock::Clock; - use std::option::Option; - use std::string::String; - use std::ascii; - - public struct MutableShared has key { - id: UID, - value: u64, - } - - fun init(ctx: &mut TxContext) { - transfer::share_object(MutableShared { - id: object::new(ctx), - value: 1, - }) - } - - public entry fun use_clock(_clock: &Clock) {} - - public entry fun list( - item: T, - ctx: &mut TxContext - ) { - transfer::public_transfer(item, tx_context::sender(ctx)) - } - - public fun return_struct( - item: T, - ): T { - item - } - - public entry fun value(clock: &MutableShared) { - assert!(clock.value > 10, 2); - } - - public entry fun set_value(clock: &mut MutableShared) { - clock.value = 20; - } - - public entry fun delete_value(clock: MutableShared) { - let MutableShared { id, value: _ } = clock; - object::delete(id); - } - - public fun test_abort() { - abort 1 - } - - public fun addr(_: address) {} - public fun id(_: ID) {} - - public fun ascii_(_: ascii::String) {} - public fun string(_: String) {} - - public fun vec(_: vector) {} - public fun opt(_: Option) {} - - public fun ints(_u8: u8, _u16: u16, _u32: u32, _u64: u64, _u128: u128, _u256: u256) {} - public fun boolean(_bool: bool) {} +module serializer::serializer_tests; + +use std::ascii; +use std::string::String; +use sui::clock::Clock; + +public struct MutableShared has key { + id: UID, + value: u64, +} + +fun init(ctx: &mut TxContext) { + transfer::share_object(MutableShared { + id: object::new(ctx), + value: 1, + }) +} + +public entry fun use_clock(_clock: &Clock) {} + +public entry fun list(item: T, ctx: &mut TxContext) { + transfer::public_transfer(item, tx_context::sender(ctx)) +} + +public fun return_struct(item: T): T { + item +} + +public entry fun value(clock: &MutableShared) { + assert!(clock.value > 10, 2); +} + +public entry fun set_value(clock: &mut MutableShared) { + clock.value = 20; +} + +public entry fun delete_value(clock: MutableShared) { + let MutableShared { id, value: _ } = clock; + object::delete(id); +} + +public fun test_abort() { + abort 1 +} + +public fun addr(_: address) {} + +public fun id(_: ID) {} + +public fun ascii_(_: ascii::String) {} + +public fun string(_: String) {} + +public fun vec(_: vector) {} + +public fun opt(_: Option) {} + +public fun ints( + _u8: u8, + _u16: u16, + _u32: u32, + _u64: u64, + _u128: u128, + _u256: u256, +) {} + +public fun boolean(_bool: bool) {} + +public fun some(opt: Option): T { + opt.destroy_some() +} + +public fun none(opt: Option) { + opt.destroy_none() } diff --git a/sdk/typescript/test/e2e/data/tto/sources/tto1.move b/sdk/typescript/test/e2e/data/tto/sources/tto1.move index d1d48e5de281c..b7ee4f4c20a5c 100644 --- a/sdk/typescript/test/e2e/data/tto/sources/tto1.move +++ b/sdk/typescript/test/e2e/data/tto/sources/tto1.move @@ -1,47 +1,49 @@ // Copyright (c) Mysten Labs, Inc. // SPDX-License-Identifier: Apache-2.0 -module tto::tto { - use sui::transfer::{Self, Receiving}; - - public struct A has key, store { - id: UID, - } - - public struct B has key, store { - id: UID, - } - - public fun start(ctx: &mut TxContext) { - let a = A { id: object::new(ctx) }; - let a_address = object::id_address(&a); - let b = B { id: object::new(ctx) }; - let c = B { id: object::new(ctx) }; - transfer::share_object(c); - transfer::public_transfer(a, tx_context::sender(ctx)); - transfer::public_transfer(b, a_address); - } - - public entry fun receiver(parent: &mut A, x: Receiving) { - let b = transfer::receive(&mut parent.id, x); - transfer::public_transfer(b, @tto); - } - - public entry fun deleter(parent: &mut A, x: Receiving) { - let B { id } = transfer::receive(&mut parent.id, x); - object::delete(id); - } - - public fun return_(parent: &mut A, x: Receiving): B { - transfer::receive(&mut parent.id, x) - } - - public entry fun delete_(b: B) { - let B { id } = b; - object::delete(id); - } - - public fun invalid_call_immut_ref(_parent: &mut A, _x: &Receiving) { } - public fun invalid_call_mut_ref(_parent: &mut A, _x: &mut Receiving) { } - public fun dropper(_parent: &mut A, _x: Receiving) { } +module tto::tto; + +use sui::transfer::Receiving; + +public struct A has key, store { + id: UID, } + +public struct B has key, store { + id: UID, +} + +public fun start(ctx: &mut TxContext) { + let a = A { id: object::new(ctx) }; + let a_address = object::id_address(&a); + let b = B { id: object::new(ctx) }; + let c = B { id: object::new(ctx) }; + transfer::share_object(c); + transfer::public_transfer(a, tx_context::sender(ctx)); + transfer::public_transfer(b, a_address); +} + +public entry fun receiver(parent: &mut A, x: Receiving) { + let b = transfer::receive(&mut parent.id, x); + transfer::public_transfer(b, @tto); +} + +public entry fun deleter(parent: &mut A, x: Receiving) { + let B { id } = transfer::receive(&mut parent.id, x); + object::delete(id); +} + +public fun return_(parent: &mut A, x: Receiving): B { + transfer::receive(&mut parent.id, x) +} + +public entry fun delete_(b: B) { + let B { id } = b; + object::delete(id); +} + +public fun invalid_call_immut_ref(_parent: &mut A, _x: &Receiving) {} + +public fun invalid_call_mut_ref(_parent: &mut A, _x: &mut Receiving) {} + +public fun dropper(_parent: &mut A, _x: Receiving) {} diff --git a/sdk/typescript/test/e2e/txn-builder.test.ts b/sdk/typescript/test/e2e/txn-builder.test.ts index 75486345488be..3b86ab45a321c 100644 --- a/sdk/typescript/test/e2e/txn-builder.test.ts +++ b/sdk/typescript/test/e2e/txn-builder.test.ts @@ -208,6 +208,47 @@ describe('Transaction Builders', () => { retry: 10, }, ); + + it('builds object options', async () => { + const tx = new Transaction(); + + tx.moveCall({ + target: `${packageId}::serializer_tests::none`, + typeArguments: ['0x2::coin::Coin<0x2::sui::SUI>'], + arguments: [ + tx.object.option({ + type: '0x2::coin::Coin<0x2::sui::SUI>', + value: null, + }), + ], + }); + const coin = tx.splitCoins(tx.gas, [1]); + const coin2 = tx.moveCall({ + target: `${packageId}::serializer_tests::some`, + typeArguments: ['0x2::coin::Coin<0x2::sui::SUI>'], + arguments: [ + tx.object.option({ + type: '0x2::coin::Coin<0x2::sui::SUI>', + value: coin, + }), + ], + }); + + const coin3 = tx.moveCall({ + target: `${packageId}::serializer_tests::some`, + typeArguments: ['0x2::coin::Coin<0x2::sui::SUI>'], + arguments: [ + tx.object.option({ + type: '0x2::coin::Coin<0x2::sui::SUI>', + value: coin2, + }), + ], + }); + + tx.transferObjects([coin3], toolbox.keypair.toSuiAddress()); + + await validateTransaction(toolbox.client, toolbox.keypair, tx); + }); }); async function validateTransaction(client: SuiClient, signer: Keypair, tx: Transaction) { diff --git a/sdk/typescript/test/e2e/utils/setup.ts b/sdk/typescript/test/e2e/utils/setup.ts index 63362790eee31..cdbd967576445 100644 --- a/sdk/typescript/test/e2e/utils/setup.ts +++ b/sdk/typescript/test/e2e/utils/setup.ts @@ -178,6 +178,7 @@ export async function publishPackage(packagePath: string, toolbox?: TestToolbox) { encoding: 'utf-8' }, ), ); + const tx = new Transaction(); const cap = tx.publish({ modules, diff --git a/sdk/typescript/test/unit/arguments.test.ts b/sdk/typescript/test/unit/arguments.test.ts index 2748d8f5b626d..6d7a7e2bdfd0b 100644 --- a/sdk/typescript/test/unit/arguments.test.ts +++ b/sdk/typescript/test/unit/arguments.test.ts @@ -30,6 +30,18 @@ describe('Arguments helpers', () => { Arguments.object.clock(), Arguments.object.random(), Arguments.object.denyList(), + Arguments.object.option({ + type: '0x123::example::Thing', + value: '0x456', + }), + Arguments.object.option({ + type: '0x123::example::Thing', + value: Arguments.object('0x456'), + }), + Arguments.object.option({ + type: '0x123::example::Thing', + value: null, + }), ]; const tx = new Transaction(); @@ -42,6 +54,54 @@ describe('Arguments helpers', () => { expect(tx.getData()).toMatchInlineSnapshot(` { "commands": [ + { + "$kind": "MoveCall", + "MoveCall": { + "arguments": [ + { + "$kind": "Input", + "Input": 9, + "type": "object", + }, + ], + "function": "some", + "module": "option", + "package": "0x0000000000000000000000000000000000000000000000000000000000000001", + "typeArguments": [ + "0x123::example::Thing", + ], + }, + }, + { + "$kind": "MoveCall", + "MoveCall": { + "arguments": [ + { + "$kind": "Input", + "Input": 9, + "type": "object", + }, + ], + "function": "some", + "module": "option", + "package": "0x0000000000000000000000000000000000000000000000000000000000000001", + "typeArguments": [ + "0x123::example::Thing", + ], + }, + }, + { + "$kind": "MoveCall", + "MoveCall": { + "arguments": [], + "function": "none", + "module": "option", + "package": "0x0000000000000000000000000000000000000000000000000000000000000001", + "typeArguments": [ + "0x123::example::Thing", + ], + }, + }, { "$kind": "MoveCall", "MoveCall": { @@ -91,6 +151,18 @@ describe('Arguments helpers', () => { "Input": 8, "type": "object", }, + { + "$kind": "Result", + "Result": 0, + }, + { + "$kind": "Result", + "Result": 1, + }, + { + "$kind": "Result", + "Result": 2, + }, ], "function": "bar", "module": "foo", @@ -176,6 +248,12 @@ describe('Arguments helpers', () => { "objectId": "0x0000000000000000000000000000000000000000000000000000000000000403", }, }, + { + "$kind": "UnresolvedObject", + "UnresolvedObject": { + "objectId": "0x0000000000000000000000000000000000000000000000000000000000000456", + }, + }, ], "sender": null, "version": 2, diff --git a/sdk/typescript/test/unit/object-inputs.test.ts b/sdk/typescript/test/unit/object-inputs.test.ts index 25d834c6065ad..25db4ad3de175 100644 --- a/sdk/typescript/test/unit/object-inputs.test.ts +++ b/sdk/typescript/test/unit/object-inputs.test.ts @@ -34,12 +34,72 @@ describe('Transaction inputs', () => { tx.object.clock(), tx.object.random(), tx.object.denyList(), + tx.object.option({ + type: '0x123::example::Thing', + value: '0x456', + }), + tx.object.option({ + type: '0x123::example::Thing', + value: tx.object('0x456'), + }), + tx.object.option({ + type: '0x123::example::Thing', + value: null, + }), ], }); expect(tx.getData()).toMatchInlineSnapshot(` { "commands": [ + { + "$kind": "MoveCall", + "MoveCall": { + "arguments": [ + { + "$kind": "Input", + "Input": 9, + "type": "object", + }, + ], + "function": "some", + "module": "option", + "package": "0x0000000000000000000000000000000000000000000000000000000000000001", + "typeArguments": [ + "0x123::example::Thing", + ], + }, + }, + { + "$kind": "MoveCall", + "MoveCall": { + "arguments": [ + { + "$kind": "Input", + "Input": 9, + "type": "object", + }, + ], + "function": "some", + "module": "option", + "package": "0x0000000000000000000000000000000000000000000000000000000000000001", + "typeArguments": [ + "0x123::example::Thing", + ], + }, + }, + { + "$kind": "MoveCall", + "MoveCall": { + "arguments": [], + "function": "none", + "module": "option", + "package": "0x0000000000000000000000000000000000000000000000000000000000000001", + "typeArguments": [ + "0x123::example::Thing", + ], + }, + }, { "$kind": "MoveCall", "MoveCall": { @@ -89,6 +149,18 @@ describe('Transaction inputs', () => { "Input": 8, "type": "object", }, + { + "$kind": "Result", + "Result": 0, + }, + { + "$kind": "Result", + "Result": 1, + }, + { + "$kind": "Result", + "Result": 2, + }, ], "function": "bar", "module": "foo", @@ -174,6 +246,12 @@ describe('Transaction inputs', () => { "objectId": "0x0000000000000000000000000000000000000000000000000000000000000403", }, }, + { + "$kind": "UnresolvedObject", + "UnresolvedObject": { + "objectId": "0x0000000000000000000000000000000000000000000000000000000000000456", + }, + }, ], "sender": null, "version": 2,