Skip to content

Feature/Sui Integration #48

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 30 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
975006b
chore: install sui wallet dependencies
owanemi Apr 20, 2025
32bae98
added suiHelper types
owanemi Apr 21, 2025
246bd1e
feat(utils): added sui provider
owanemi Apr 23, 2025
2e7ec41
feat: added createWallet function
owanemi Apr 24, 2025
610916a
feat: implemented generateWalletFromMnemonic function
owanemi Apr 24, 2025
4b0465f
feat: implemented generateAddressFromPrivateKey function
owanemi Apr 24, 2025
65ff23f
feat: implemented getBalance function
owanemi Apr 24, 2025
521fb6c
added coin decimal division for getBalance
owanemi Apr 24, 2025
8c85aac
feat: implemented transfer function
owanemi Apr 24, 2025
3429346
feat: implemented getTransaction function
owanemi Apr 24, 2025
9dd9af1
feat: implemented getTokenInfo function
owanemi Apr 24, 2025
bda9524
updated SmartContractPayload Interface to account for sui
owanemi Apr 25, 2025
f2b81f6
added module property for SmartContractPayload Interface
owanemi Apr 25, 2025
46af824
added packageId property for SmartContractPayload Interface
owanemi Apr 25, 2025
3d8ded2
added sender property for SmartContractPayload Interface
owanemi Apr 25, 2025
06dae01
feat: implemented smartContractCall for sui
owanemi Apr 25, 2025
496d3da
chore: format with prettier
owanemi Apr 25, 2025
c3268f4
added suiHelper to wallet index file
owanemi Apr 25, 2025
e1f89e8
added typeArguments property to smartContractPayloadInterface
owanemi Apr 25, 2025
bce096a
added typeArguments for move calls
owanemi Apr 25, 2025
93a0254
finished sui wallet tests for all fucntions
owanemi Apr 25, 2025
783ab06
update mysten/sui dependency
owanemi Apr 25, 2025
145089a
added typed transaction builder for transfer and contract call
owanemi Apr 25, 2025
bbd6702
fix ESM module test errors
owanemi Apr 29, 2025
65feac3
resolve ESM module issue
owanemi Apr 29, 2025
e7353b2
added sui to test script to package.json
owanemi Apr 30, 2025
3a5b5a1
account for Sui features on readme
owanemi Apr 30, 2025
ffe5a43
added sui to test script to package.json
owanemi Apr 30, 2025
4ed2187
update readme methods for sui
owanemi Apr 30, 2025
ea270d9
update README with correct sui rpcUrl
owanemi Apr 30, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions .babelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"env": {
"test": {
"presets": [
["@babel/preset-env", { "targets": { "node": "current" } }],
"@babel/preset-typescript"
],
"plugins": [
"@babel/plugin-transform-modules-commonjs"
]
},
"production": {
"presets": [
["@babel/preset-env", { "targets": { "node": "current" }, "modules": false }],
"@babel/preset-typescript"
]
}
}
}
142 changes: 139 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ The following methods are available with this SDK:
- [Response](#response-8)
- [Tron Network](#tron-network)
- [Response](#response-9)
- [Sui Network](#Sui-Network)
- [Response](#response-11)
- [Encryptions](#encryptions)
- [Encrypt Private Key](#encrypt-private-key)
- [Response](#response-10)
Expand All @@ -84,11 +86,13 @@ The following methods are available with this SDK:
- [Response](#response-14)
- [Get TRC20 Token Info](#get-tron-token-info)
- [Response](#response-15)
- [Get Sui Coin Info](#get-sui-coin-info)
- [Response](#response-16)
- [Smart Contract Call](#smart-contract-call)
- [Ethereum network](#ethereum-network-1)
- [Waves network](#waves-network-1)
- [Tron network](#tron-network-1)
- [Response](#response-17)
- [Sui Network](#sui-network-1)
- [Want to contribute?](#want-to-contribute)

### Generate mnemonic
Expand Down Expand Up @@ -137,11 +141,15 @@ const wallet = await multichainWallet.createWallet({
network: 'waves',
});

// Creating a Tron wallet
// Creating a Tron wallet.
const wallet = await multichainWallet.createWallet({
network: 'tron',
});

//Creating a Sui wallet.
const wallet = await multichainWallet.createWallet({
network: 'sui',
})
```

#### Response
Expand Down Expand Up @@ -202,6 +210,13 @@ const data = await multichainWallet.getBalance({
address: 'TDdHvW9nU1JaX1P7roYtDvjErTTR17GPJJ',
rpcUrl: 'https://nile.trongrid.io',
});

// Get the Sui balance of an address.
const data = await multichainWallet.getBalance({
network: 'sui',
address: '0xc8ef1c69d448b8c373c6de6f7170b0dc4ab8804591601c77ac6d6d0aad9fb914',
rpcUrl: 'https://fullnode.testnet.sui.io:443',
});
```

#### Tokens
Expand Down Expand Up @@ -231,13 +246,21 @@ const data = await multichainWallet.getBalance({
tokenAddress: '39pnv8FVf3BX3xwtC6uhFxffy2sE3seXCPsf25eNn6qG',
});

// Get the balance of a token on tron.
// Get the balance of a token on Tron.
const data = await multichainWallet.getBalance({
network: 'tron',
address: 'TDdHvW9nU1JaX1P7roYtDvjErTTR17GPJJ',
rpcUrl: 'https://nile.trongrid.io',
tokenAddress: 'TXLAQ63Xg1NAzckPwKHvzw7CSEmLMEqcdj',
});

// Get the balance of a token on Sui.
const data = await multichainWallet.getBalance({
network: 'sui',
address: '0xc8ef1c69d448b8c373c6de6f7170b0dc4ab8804591601c77ac6d6d0aad9fb914',
rpcUrl: 'https://fullnode.testnet.sui.io:443',
tokenAddress: '0xa1ec7fc00a6f40db9693ad1415d0c193ad3906494428cf252621037bd7117e29::usdc::USDC',
});
```

#### Response
Expand Down Expand Up @@ -299,6 +322,14 @@ const wallet = multichainWallet.generateWalletFromMnemonic({
'mushroom deliver work spray hire nuclear wrong deputy march six midnight outside motor differ adult',
network: 'tron',
});

// Generate a Sui Wallet from mnemonic.
const wallet = multichainWallet.generateWalletFromMnemonic({
mnemonic:
'ship friend modify merit dune tower ritual off assault resemble vintage solid',
derivationPath: "m/44'/784'/0'/0'/0'", // Leave empty to use default derivation path
network: 'sui',
});
```

#### Response
Expand Down Expand Up @@ -342,6 +373,14 @@ const address = multichainWallet.getAddressFromPrivateKey({
'fa01dc6efd5fd64e4897aadf255ae715cf34138c7ada5f6a7efb0bdd0bd9c8c4',
network: 'tron',
});

// Get the address from the private key on the Sui network.
const address = multichainWallet.getAddressFromPrivateKey({
privateKey:
'suiprivkey1qpppfvzg767qahlw6eu09m2ql3uvc59xqgt3l0un06lvnf8yjxac6v37z3e',
network: 'sui',
});

```

#### Response
Expand Down Expand Up @@ -391,6 +430,13 @@ const receipt = await multichainWallet.getTransaction({
network: 'tron',
rpcUrl: 'https://nile.trongrid.io',
});

// Get the transaction receipt on Sui network.
const receipt = await multichainWallet.getTransaction({
hash: 'AsU5WsBm8kZtuC2hQNyX3zv3CpvHUznE3mLEVewsgp4V',
network: 'sui',
rpcUrl: 'https://fullnode.testnet.sui.io:443',
});
```

#### Response
Expand Down Expand Up @@ -623,6 +669,38 @@ const transfer = await multichainWallet.transfer({
..object;
}
```
#### Sui Network

Allows for the transfer of SUI and Sui tokens.

```javascript
// Transferring SUI from one address to another.
const transfer = await multichainWallet.transfer({
recipientAddress: '0x7264e741063b6b064cdb780b44578db213cdff9e5641abb2c34a5b5c55307579',
amount: 0.1,
network: sui,
rpcUrl: 'https://fullnode.testnet.sui.io:443',
privateKey: 'suiprivkey1qpppfvzg767qahlw6eu09m2ql3uvc59xqgt3l0un06lvnf8yjxac6v37z3e',
})

// Transferring Sui coins from one address to another.
const transfer = await multichainWallet.transfer({
recipientAddress: '0x7264e741063b6b064cdb780b44578db213cdff9e5641abb2c34a5b5c55307579',
tokenAddress: '0xa1ec7fc00a6f40db9693ad1415d0c193ad3906494428cf252621037bd7117e29::usdc::USDC',
amount: 0.1,
network: sui,
rpcUrl: 'https://fullnode.testnet.sui.io:443',
privateKey: 'suiprivkey1qpppfvzg767qahlw6eu09m2ql3uvc59xqgt3l0un06lvnf8yjxac6v37z3e',
})
```

#### Response
```bash
{
digest
..object;
}
```

### Encryptions

Expand Down Expand Up @@ -777,6 +855,30 @@ const info = await multichainWallet.getTokenInfo({
}
```

#### Get Sui Coin Info

Allows for fetching Sui coin

```javascript
const info = await multichainWallet.getTokenInfo({
address: '0xa1ec7fc00a6f40db9693ad1415d0c193ad3906494428cf252621037bd7117e29::usdc::USDC',
network: 'sui',
rpcUrl: 'https://fullnode.testnet.sui.io:443',
});
```

#### Response
```javascript
{
name: 'USDC',
symbol: 'USDC',
address: '0xa1ec7fc00a6f40db9693ad1415d0c193ad3906494428cf252621037bd7117e29::usdc::USDC',
decimals: 6,
logoUrl: 'https://www.circle.com/hubfs/Brand/USDC/USDC_icon_32x32.png',
totalSupply: '2526980560742103'
}
```

### Smart Contract Call

This can be used to make custom smart contract interaction by specifying the contract ABI and function types.
Expand Down Expand Up @@ -911,6 +1013,35 @@ const data = await multichainWallet.smartContractCall({
});
```

#### Sui network
```javascript
// Calling a write smart contract function
const data = await multichainWallet.smartContractCall({
contractAddress: '0x086162ecfab930c92b2773f0f878f4998bad6c4fd9d2135fc58f8592ed9f4854::nft::mint', // The contractAddress is the form `packageId::module_name::method`
params: ['nftName', 'nftDescription', '0xc8ef1c69d448b8c373c6de6f7170b0dc4ab8804591601c77ac6d6d0aad9fb914', 'nftImgUrl'],
paramTypes: ['string', 'string', 'address', 'string'],
method: 'mint',
methodType: 'write',
network: 'sui',
rpcUrl: 'https://fullnode.testnet.sui.io:443',
privateKey: testPrivateKey,
gasLimit: 10_000_000, // 0.01 SUI
})

// Calling a read smart contract function
const data = await multichainWallet.smartContractCall({
// This calls the owner function to retrieve the owner of a counter object in a module
contractAddress: '0x086162ecfab930c92b2773f0f878f4998bad6c4fd9d2135fc58f8592ed9f4854::counter::owner', // The contractAddress is the form `packageId::module_name::method`
params: ['0xaf7a0a1346420a575015429cc4289a1d55faf37d93fa69bb07a1619b3be5665c'], //This is the counter object we want to get its owner
paramTypes: ['object'],
method: 'owner',
methodType: 'read',
network: 'sui',
rpcUrl: 'https://fullnode.testnet.sui.io:443',
sender: '0xc8ef1c69d448b8c373c6de6f7170b0dc4ab8804591601c77ac6d6d0aad9fb914',
})
```

Some of the parameters available in this function are:

- The **method** parameter is the name of the smart contract function to be interacted with.
Expand All @@ -927,6 +1058,11 @@ The optional parameters that the object takes in are: value, contractAbi, gas pr
- The **private key** is a string parameter that can be passed to use as the signer. It is used to sign the transaction. This parameter is not needed when calling a smart contract read function.
- The **payment** (only on Waves) payment is the payment (WAVES or Waves Asset) sent to the smart contract while interacting with it. If the smart contract function does not require any payment.
- The **feeLimt** (only on Tron) is the max amount of fee you're willing to pay for the transaction
- The **paramTypes** (only on Sui) it is the list of types for each parameter expected by the function e.g `u64`, `address`, `vector<u8>`. Used to define the function's signature and how to encode the arguments.
- The **typeArguments** (only on Sui) this is an optional field, they are concrete types for generic parameters, basically for interacting with the specific type of an object. Example, in this move function `public fun transfer<T>(coin: Coin<T>, recipient: address)` This function can transfer any kind of coin, but you must specify the actual coin type when you call it. An example of calling the fucntion:
`transfer<0x2::usdc::USDC>(my_usdc_coin, recipient_address)`
Here, `0x2::usdc::USDC` is the typeArgument for `T` and `my_usdc_coin` is the objectId of your usdc coin
- The **sender** (only on Sui) this is the sui address only for view transactions.

#### Response

Expand Down
15 changes: 14 additions & 1 deletion jest.config.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,27 @@
const config = {
testTimeout: 100000,
testTimeout: 100000,
moduleNameMapper: {
'^axios$': 'axios/dist/axios.js',
},
globals: {
'ts-jest': {
isolatedModules: true,
useESM: true,
},
},
preset: 'ts-jest/presets/default-esm',
setupFiles: ['./jest.setup.js'],
transform: {
'^.+\\.(ts|js)$': ['babel-jest', {
presets: [
['@babel/preset-env', { targets: { node: 'current' } }],
'@babel/preset-typescript'
],
}]
},
transformIgnorePatterns: [
'/node_modules/(?!(@mysten/sui|valibot)/)'
],
};

module.exports = config;
14 changes: 11 additions & 3 deletions jest.setup.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,25 @@
const crypto = require('crypto');
const { TextEncoder, TextDecoder } = require('util');
const fetch = require('node-fetch');

// Add TextEncoder/TextDecoder to global
global.TextEncoder = TextEncoder;
global.TextDecoder = TextDecoder;
global.fetch = fetch;

// Setup crypto
Object.defineProperty(global, 'crypto', {
value: {
getRandomValues: arr => crypto.randomFillSync(arr),
subtle: crypto.subtle
},
});

// Patch @noble/hashes
try {
const noble = require('@noble/hashes/utils');
if (noble) {
noble.randomBytes = length => {
return crypto.randomBytes(length);
};
noble.randomBytes = (length) => crypto.randomBytes(length);
}
} catch (e) {
console.warn('Could not patch @noble/hashes');
Expand Down
10 changes: 10 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
"test:sol": "tsdx test --testPathPattern=solana",
"test:tron": "tsdx test --testPathPattern=tron",
"test:waves": "tsdx test --testPathPattern=waves",
"test:sui": "tsdx test --testPathPattern=sui",
"lint": "tsdx lint",
"prepare": "tsdx build",
"size": "size-limit",
Expand Down Expand Up @@ -76,15 +77,24 @@
}
],
"devDependencies": {
"@babel/core": "^7.26.10",
"@babel/plugin-transform-modules-commonjs": "^7.26.3",
"@babel/preset-env": "^7.26.9",
"@babel/preset-typescript": "^7.27.0",
"@size-limit/preset-small-lib": "^7.0.8",
"babel-jest": "^29.7.0",
"cross-env": "^7.0.3",
"husky": "^7.0.4",
"node-fetch": "2.6.7",
"size-limit": "^7.0.8",
"ts-jest": "^29.3.2",
"tsdx": "^0.14.1",
"tslib": "^2.3.1",
"typescript": "^4.6.3"
},
"dependencies": {
"@bitgo/utxo-lib": "https://github.com/ren-forks/bitgo-utxo-lib#b848585e65b42c48b98c207e72d7d3006c9a5da0",
"@mysten/sui": "^1.28.2",
"@solana/spl-token": "^0.2.0",
"@solana/web3.js": "^1.39.1",
"@truffle/hdwallet-provider": "^2.0.5",
Expand Down
Loading