Skip to main content

Transaction Plugin for Sui TypeScript SDK

To use Move Registry (MVR) names in programmable transaction blocks (PTBs), build the transaction with a @mysten/sui client. Starting with @mysten/sui v2.0, MVR resolution is built into the client and configured through its mvr option, so there is no plugin to register. For build-time resolution, consider the @mysten/mvr-static plugin instead.

The Move Registry (MVR, pronounced mover) support in the Sui TypeScript SDK offers builders a seamless experience when constructing programmable transaction blocks (PTBs) using MVR names.

The client resolves MVR names to their respective addresses while building the PTB, caching the results during each runtime.

This also applies to type names, especially across package upgrades.

The built-in resolver uses a runtime API to resolve named packages and types. While this is beneficial to the user experience, it naturally comes with considerations around performance, availability, and security.

For this reason, consider using the @mysten/mvr-static plugin, which statically resolves all the package addresses and types during the build. The plugin caches your MVR references and exports them to a resolution file that you pass to the client as overrides.

This approach offers a couple of benefits:

  • Enhanced user experience of leveraging MVR in your PTBs for names and types, for both Mainnet and Testnet
  • Performance (no extra calls to the MVR endpoint) and security of statically resolving MVR references at build time

Check the NPM page for the @mysten/mvr-static plugin to learn more.

How to use​

info

Built-in resolution is available starting from @mysten/sui v2.0. Versions 1.25.0 through 1.x used a namedPackagesPlugin export that v2.0 removed. The v2.0 migration guide shows how to replace the plugin registration with client options.

Every @mysten/sui client that implements the core API, such as SuiGrpcClient and SuiGraphQLClient, includes an MVR resolver. Configure it through the client's mvr option, then pass the client when you build the transaction.

Runtime resolution uses the client's mvr option. For build-time resolution, see Recommended usage.

Endpoints​

Mysten Labs provides public good endpoints for MVR resolution. The client selects the endpoint that matches its network option, so you do not need to set a URL on Mainnet or Testnet. Set mvr.url to use a different endpoint.

Mainnet: https://mainnet.mvr.mystenlabs.com
Testnet: https://testnet.mvr.mystenlabs.com

Configure the client​

Resolution happens when you build a transaction that contains MVR names and pass a client to build. Methods that build on your behalf, such as signAndExecuteTransaction, pass the client for you. Building a transaction that contains MVR names without a client throws an error.

The mvr option accepts the following fields:

  • url: The MVR endpoint. Defaults to the Mainnet or Testnet endpoint that matches the client's network.
  • pageSize: The number of names sent in each resolution request. Defaults to 50.
  • overrides: Package and type addresses that the client uses without calling the endpoint. See Define overrides.
/** Configure MVR resolution on the client */

import { SuiGrpcClient } from "@mysten/sui/grpc";
import { Transaction } from "@mysten/sui/transactions";

const client = new SuiGrpcClient({
baseUrl: 'https://fullnode.mainnet.sui.io:443',
network: 'mainnet',
// Optional: the client picks the endpoint from `network`.
mvr: { url: 'https://mainnet.mvr.mystenlabs.com' },
});

const transaction = new Transaction();

// Add commands that use MVR names, then build with the client.
const bytes = await transaction.build({ client });
/** Resolve names per network */

const clients = {
mainnet: new SuiGrpcClient({ baseUrl: 'https://fullnode.mainnet.sui.io:443', network: 'mainnet' }),
testnet: new SuiGrpcClient({ baseUrl: 'https://fullnode.testnet.sui.io:443', network: 'testnet' }),
};

async function buildTransaction(network: 'mainnet' | 'testnet') {
const transaction = new Transaction();

// continue with your transaction.

return transaction.build({ client: clients[network] });
}

Define overrides​

If you want to resolve names locally (for continuous integration), or you want to cache results yourself (without the @mysten/mvr-static generator), you can define overrides for the package addresses and types. The client uses an override without calling the endpoint, so overrides also work on networks that have no default endpoint.

The client validates overrides when you construct it. Each package override needs a valid MVR package name and package ID, and each type override must name a first-level type, so list each generic type parameter as its own entry.

const overrides = {
packages: {
'@suifrens/accessories': '0xe177697e191327901637f8d2c5ffbbde8b1aaac27ec1024c4b62d1ebd1cd7430',
},
types: {
'@suifrens/core::suifren::SuiFren': '0x80d7de9c4a56194087e0ba0bf59492aa8e6a5ee881606226930827085ddf2332::suifren::SuiFren',
'@suifrens/core::bullshark::Bullshark': '0x8894fa02fc6f36cbc485ae9145d05f247a78e220814fb8419ab261bd81f08f32::bullshark::Bullshark',
}
}

const client = new SuiGrpcClient({
baseUrl: '<fullnode endpoint for the network>',
network: 'mainnet',
mvr: { overrides },
});

Before and after example​

caution

The tabs show simplified examples for clarity. Actual addresses or names might differ.

Example of a PTB before MVR:

const transaction = new Transaction();

// Testnet
// Notice how the suifren type has a V1 outer package id, and a V2 inner type package id,
// even if they are part of the same package upgrades.
transaction.moveCall({
target: `0xe177697e191327901637f8d2c5ffbbde8b1aaac27ec1024c4b62d1ebd1cd7430::accessories::equip`,
arguments: [..],
typeArguments: [
`0x80d7de9c4a56194087e0ba0bf59492aa8e6a5ee881606226930827085ddf2332::suifren::SuiFren<0x297d8afb6ede450529d347cf9254caeea2b685c8baef67b084122291ebaefb38::bullshark::Bullshark>`
]
});

// Mainnet
transaction.moveCall({
target: `0x54800ebb4606fd0c03b4554976264373b3374eeb3fd63e7ff69f31cac786ba8c::accessories::equip`,
arguments: [..],
typeArguments: [
`0xee496a0cc04d06a345982ba6697c90c619020de9e274408c7819f787ff66e1a1::suifren::SuiFren<0x8894fa02fc6f36cbc485ae9145d05f247a78e220814fb8419ab261bd81f08f32::bullshark::Bullshark>`
]
});