SkillAgentSearch skills...

Suidouble

Set of provider, package and object classes for javascript representation of Sui Move smart contracts. Use same code for publishing, upgrading, integration testing, interaction with smart contracts and integration in browser web3 dapps

Install / Use

/learn @suidouble/Suidouble
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

suidouble

Set of provider, package and object classes for javascript representation of Sui's smart contracts. Use same code for publishing, upgrading, integration testing, interaction with smart contracts and integration in browser dapps. Very alpha for now.

Sample applications

| Name | Stack | Online | Github | |----------|---------------|---------|--------| | sui-bot-score | Vue + suidouble | sui-bot-score | source code | | suidouble-sample-app | Vue + suidouble | suidouble-sample-app | source code | | suidouble-color | Vue + suidouble | suidouble-color | source code |

installation

npm install suidouble --save

usage

connecting

Main class to interact with blockchain is SuiMaster:

import { SuiMaster } from 'suidouble';

You can initialize it directly, if you have keypair, secret phrase, or privateKey and can use it in code (so on node.js side - server side or CLI apps):

const suiMaster = new SuiMaster({
    keypair: Ed25519Keypair || Secp256r1Keypair || Secp256k1Keypair,
    debug: true,    // echo testing messages to console
    client: 'test', // 'test', 'dev', 'local', 'main' or instance of this lib's SuiLocalTestValidator
});
const suiMaster = new SuiMaster({
    debug: false,
    privateKey: 'suiprivkey1qpwly9xrfsv50mqug706s40l58klez5q6mpchq4f5ldzktjyr4x7yhj9lf2',
    client: 'dev', 
});
const suiMaster = new SuiMaster({
    debug: false,
    phrase: 'thrive mean two thrive mean two thrive mean two thrive mean two', // secret phrase to generate keypair
    client: 'dev', 
});
const suiMaster = new SuiMaster({
    debug: false,
    phrase: 'thrive mean two thrive mean two thrive mean two thrive mean two', // secret phrase to generate keypair
    accountIndex: 1, // derive path index (you can generate few addresses with same seed phrase)
    client: 'dev', 
});
const suiMaster = new SuiMaster({
    debug: false,
    phrase: 'thrive mean two thrive mean two thrive mean two thrive mean two', // secret phrase to generate keypair
    keypairAlgo: 'secp256k1', // 'secp256r1' or 'secp256r1' or 'ed25519' default is ed25519
    client: 'dev', 
});

Also, there's option to generate pseudo-random phrases and wallets from strings, works like a charm for testing:

const suiMasterAsAdmin = new SuiMaster({ as: 'admin', client: 'dev', });
const suiMasterAsUser = new SuiMaster({ as: 'user', client: 'dev', });

On browser side, you'd probably want to use Sui wallets extensions adapters to sign message and don't store any keypairs or secret phrases in your code. So there's SuiInBrowser class for this, which can setup suiMaster instance for you. See 'Sui Move Connect in browser' section or sample UI application's code for more details.

import { SuiInBrowser } from 'suidouble';
const suiInBrowser = SuiInBrowser.getSingleton(); // you probably don't want to keep few connections, so there's singleton
/// ...
suiInBrowser.addEventListener('connected', async()=>{
    const connectedSuiMaster = await suiInBrowser.getSuiMaster(); // can post transactions now
    console.log('read-write on', suiInBrowser.getCurrentChain(), 'as', suiMaster.address);
});
suiInBrowser.connect(adapter);

Take a look at more detailed web3 connect code, sample application source code or check it online.

attaching a package

By default, suiMaster doesn't know of any smart contracts. There're 3 ways to attach one for interaction.

You can do it directly if you know contract's address (id). This is the option for browser apps and testing existing package:

const contract = suiMaster.addPackage({
    id: '0x20cded4f9df05e37b44e3be2ffa9004dec77786950719fad6083694fdca45bf2',
});
await contract.isOnChain();  

On node.js side, if you have Move's project with package code, you can attach it with path. This is the option for TDD and package publishing.

const contract = suiMaster.addPackage({
    path: '../path_to_move_project_root/',
});
await contract.isOnChain();  

Yes, it can find it's address on chain, by comparing Move's module names with package you own on chain. Works ok if you want to test upgrading or something. Also, you can attach the package only by modules names. This will work in browser too (note: you have to own this package, its UpgradeCap):

const contract = suiMaster.addPackage({
    modules: ['chat', 'anothermodulename'],
});
await contract.isOnChain();  

interacting with smart contract

SuiObject

Everyhing in Sui is an object. So is in suidouble. SuiObject's instance class follows:

suiObject.id; // '0x10cded4f9df05e37b44e3be2ffa9004dec77786950719fad6083694fdca45bf2' or something
suiObject.address; // very same, '0x10cded4f9df05e37b44e3be2ffa9004dec77786950719fad6083694fdca45bf2'
suiObject.isShared; // boolean. Is object shared (see Sui docs)
suiObject.isImmutable; // boolean. Is object immutable (see Sui docs)
suiObject.isDeleted;   // marked as removed from blockchain in result of Sui Move contract method call
suiObject.type;        // full type name, with package-module prefix, '0x20cded4f9df05e37b44e3be2ffa9004dec77786950719fad6083694fdca45bf2::chat::ChatResponse'
suiObject.typeName;    // type name with no prefixes, eg 'ChatResponse'
suiObject.fields;      // {}, object. Fields stored on blockchain
suiObject.display;     // display object stored on blockchain
suiObject.localProperties;  // {} object. Any local properties you want to attach to object. No interaction with blockchain. May be helpful to store some temp data
suiObject.isOwnedBy('0x10cded4f9df05e37b44e3be2ffa9004dec77786950719fad6083694fdca45bf2'); // is object owned by somebody or some object
/// past versions:
await suiObject.getPastObject(version); // get instance of object from the past
await suiObject.getPastObject(); // try to get previous
/// object-related transactions:
await suiObject.queryTransactionBlocks(); // returns instance of SuiPaginatedResponse

@todo: better SuiObject documentation

fetching events
const events = await contract.fetchEvents('modulename', {eventTypeName: 'ChatResponseCreated', order: 'descending'});
// events is instance of SuiPaginatedResponse. Data is stored in .data, has method to fetch next page - .nextPage();
while (events.hasNextPage) {
    for (const event of events.data) {
        // event is instance of SuiEvent 
        console.log('event', event.parsedJson); // data on blockchain
        console.log('timestamp', event.timestampMs); // time event emited
    }
    await events.nextPage();
}
// const events = await contract.fetchEvents('modulename', {order: 'descending'}); // or all module events
subscribing to events

*** Subscribe to Events is deprecated in Sui SDK *** You should plan to use different architecture in your application.

executing smart contract method
// executing method with parameters of (chat_shop: &ChatShop, metadata: vector<u8>, text: vector<u8>)
const res = await contract.moveCall('chat', 'post', ['0x10cded4f9df05e37b44e3be2ffa9004dec77786950719fad6083694fdca45bf2', contract.arg('vector<u8>', [3,24,55]), contract.arg('string', 'anotherparam') ]);
// or await contract.modules.chat.moveCall('methodname', ['somedata', [3,24,55], 'anotherparam']);
    console.log(res);
    for (const object of res.created) {
        console.log('created', object.address, 'with type of', object.typeName); // instances of SuiObject (@todo: write documentation for it)
    }
    for (const object of res.mutated) {
        console.log('mutated', object.address, 'with type of', object.typeName); 
    }
    for (const object of res.deleted) {
        console.log('deleted', object.address, 'with type of', object.typeName, object.isDeleted);
    }
move methods argumets types

Sui forces you to specify argument type in SDK v1.0, so we are going to follow this paradigm. With few little helpers. Both SuiPackage and SuiPackageModule have methods to make Inputs.Pure with bcs for you based on the desired type, you can use for executing suiPackage.moveCall or suiPackageModule.moveCall:

const arguments = [];
arguments.push(contract.arg('bool', true));
arguments.push(contract.arg('u8', 222));
arguments.push(contract.arg('u16', 2222));
arguments.push(contract.arg('u32', 3333));
arguments.push(contract.arg('u64', 4444));
arguments.push(contract.arg('u128', 5555));
arguments.push(contract.arg('u256', 6666));
arguments.push(contract.arg('address', '0xd9a95d7cc137f71dd7766f02791536453062a7509e9f461620cc4f583b09134c'));
arguments.push(contract.arg('string
View on GitHub
GitHub Stars24
CategoryDevelopment
Updated29d ago
Forks6

Languages

JavaScript

Security Score

95/100

Audited on Mar 3, 2026

No findings