@scallop-io/sui-kit
Advanced tools
Comparing version 0.37.1 to 0.38.0
@@ -27,3 +27,2 @@ "use strict"; | ||
SuiKit: () => SuiKit, | ||
SuiRpcProvider: () => SuiRpcProvider, | ||
SuiTxBlock: () => SuiTxBlock, | ||
@@ -154,149 +153,7 @@ TransactionBlock: () => import_sui10.TransactionBlock | ||
// src/libs/suiRpcProvider/index.ts | ||
var import_sui6 = require("@mysten/sui.js"); | ||
// src/libs/suiRpcProvider/faucet.ts | ||
var import_sui4 = require("@mysten/sui.js"); | ||
var import_ts_retry_promise = require("ts-retry-promise"); | ||
var requestFaucet = async (address, provider) => { | ||
console.log("\nRequesting SUI from faucet for address: ", address); | ||
const headers = { | ||
authority: "faucet.testnet.sui.io", | ||
method: "POST", | ||
path: "/gas", | ||
scheme: "https", | ||
accept: "*/*", | ||
"accept-encoding": "gzip, deflate, br", | ||
"accept-language": "zh-CN,zh;q=0.9,en;q=0.8,ja;q=0.7", | ||
"content-length": "105", | ||
"content-type": "application/json", | ||
origin: "chrome-extension://opcgpfmipidbgpenhmajoajpbobppdil", | ||
cookie: '_ga=GA1.1.2092533979.1664032306; sui_io_cookie={"level":["necessary","analytics"],"revision":0,"data":null,"rfc_cookie":false}; _ga_YKP53WJMB0=GS1.1.1680531285.31.0.1680531334.11.0.0; _ga_0GW4F97GFL=GS1.1.1680826187.125.0.1680826187.60.0.0; __cf_bm=6rPjXUwuzUPy4yDlZuXgDj0v7xLPpUd5z0CFGCoN_YI-1680867579-0-AZMhU7/mKUUbUlOa27LmfW6eIFkBkXsPKqYgWjpjWpj2XzDckgUsRu/pxSRGfvXCspn3w7Df+uO1MR/b+XikJU0=; _cfuvid=zjwCXMmu19KBIVo_L9Qbq4TqFXJpophG3.EvFTxqdf4-1680867579342-0-604800000', | ||
"sec-ch-ua": '"Google Chrome";v="111", "Not(A:Brand";v="8", "Chromium";v="111"', | ||
"sec-ch-ua-mobile": "?0", | ||
"sec-ch-ua-platform": "macOS", | ||
"sec-fetch-dest": "empty", | ||
"sec-fetch-mode": "cors", | ||
"sec-fetch-site": "none", | ||
"user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36" | ||
}; | ||
const resp = await (0, import_ts_retry_promise.retry)( | ||
() => provider.requestSuiFromFaucet(address, headers), | ||
{ | ||
backoff: "EXPONENTIAL", | ||
// overall timeout in 60 seconds | ||
timeout: 1e3 * 60, | ||
// skip retry if we hit the rate-limit error | ||
retryIf: (error) => !(error instanceof import_sui4.FaucetRateLimitError), | ||
logger: (msg) => console.warn(`Retry requesting faucet: ${msg}`) | ||
} | ||
); | ||
(0, import_sui4.assert)(resp, import_sui4.FaucetResponse, "Request faucet failed\n"); | ||
console.log("Request faucet success\n"); | ||
}; | ||
// src/libs/suiRpcProvider/defaultChainConfigs.ts | ||
// src/libs/suiTxBuilder/index.ts | ||
var import_sui5 = require("@mysten/sui.js"); | ||
var getDefaultNetworkParams = (networkType = "devnet") => { | ||
switch (networkType) { | ||
case "localnet": | ||
return import_sui5.localnetConnection; | ||
case "devnet": | ||
return import_sui5.devnetConnection; | ||
case "testnet": | ||
return import_sui5.testnetConnection; | ||
case "mainnet": | ||
return import_sui5.mainnetConnection; | ||
default: | ||
return import_sui5.devnetConnection; | ||
} | ||
}; | ||
// src/libs/suiRpcProvider/index.ts | ||
var SuiRpcProvider = class { | ||
/** | ||
* | ||
* @param networkType, 'testnet' | 'mainnet' | 'devnet' | 'localnet', default is 'devnet' | ||
* @param fullnodeUrl, the fullnode url, default is the preconfig fullnode url for the given network type | ||
* @param faucetUrl, the faucet url, default is the preconfig faucet url for the given network type | ||
*/ | ||
constructor({ | ||
fullnodeUrl, | ||
faucetUrl, | ||
networkType | ||
} = {}) { | ||
const defaultNetworkParams = getDefaultNetworkParams( | ||
networkType || "devnet" | ||
); | ||
this.fullnodeUrl = fullnodeUrl || defaultNetworkParams.fullnode; | ||
this.faucetUrl = faucetUrl || defaultNetworkParams.faucet; | ||
const connection = new import_sui6.Connection({ | ||
fullnode: this.fullnodeUrl, | ||
faucet: this.faucetUrl | ||
}); | ||
this.provider = new import_sui6.JsonRpcProvider(connection); | ||
} | ||
/** | ||
* Request some SUI from faucet | ||
* @Returns {Promise<boolean>}, true if the request is successful, false otherwise. | ||
*/ | ||
async requestFaucet(addr) { | ||
return requestFaucet(addr, this.provider); | ||
} | ||
async getBalance(addr, coinType) { | ||
return this.provider.getBalance({ owner: addr, coinType }); | ||
} | ||
async getObjects(ids) { | ||
const options = { showContent: true, showDisplay: true, showType: true }; | ||
const objects = await this.provider.multiGetObjects({ ids, options }); | ||
const parsedObjects = objects.map((object) => { | ||
const objectId = (0, import_sui6.getObjectId)(object); | ||
const objectType = (0, import_sui6.getObjectType)(object); | ||
const objectVersion = (0, import_sui6.getObjectVersion)(object); | ||
const objectFields = (0, import_sui6.getObjectFields)(object); | ||
const objectDisplay = (0, import_sui6.getObjectDisplay)(object); | ||
return { | ||
objectId, | ||
objectType, | ||
objectVersion, | ||
objectFields, | ||
objectDisplay | ||
}; | ||
}); | ||
return parsedObjects; | ||
} | ||
/** | ||
* @description Select coins that add up to the given amount. | ||
* @param addr the address of the owner | ||
* @param amount the amount that is needed for the coin | ||
* @param coinType the coin type, default is '0x2::SUI::SUI' | ||
*/ | ||
async selectCoins(addr, amount, coinType = "0x2::SUI::SUI") { | ||
const coins = await this.provider.getCoins({ owner: addr, coinType }); | ||
const selectedCoins = []; | ||
let totalAmount = 0; | ||
coins.data.sort((a, b) => parseInt(b.balance) - parseInt(a.balance)); | ||
for (const coinData of coins.data) { | ||
selectedCoins.push({ | ||
objectId: coinData.coinObjectId, | ||
digest: coinData.digest, | ||
version: coinData.version | ||
}); | ||
totalAmount = totalAmount + parseInt(coinData.balance); | ||
if (totalAmount >= amount) { | ||
break; | ||
} | ||
} | ||
if (!selectedCoins.length) { | ||
throw new Error("No valid coins found for the transaction."); | ||
} | ||
return selectedCoins; | ||
} | ||
}; | ||
// src/libs/suiTxBuilder/index.ts | ||
var import_sui8 = require("@mysten/sui.js"); | ||
// src/libs/suiTxBuilder/util.ts | ||
var import_sui7 = require("@mysten/sui.js"); | ||
var import_sui4 = require("@mysten/sui.js"); | ||
var getDefaultSuiInputType = (value) => { | ||
@@ -319,3 +176,3 @@ if (typeof value === "string" && value.startsWith("0x")) { | ||
const objects = args.map( | ||
(arg) => typeof arg === "string" ? txBlock.object((0, import_sui7.normalizeSuiObjectId)(arg)) : arg | ||
(arg) => typeof arg === "string" ? txBlock.object((0, import_sui4.normalizeSuiObjectId)(arg)) : arg | ||
); | ||
@@ -336,3 +193,3 @@ return txBlock.makeMoveVec({ objects }); | ||
if (typeof arg === "string" && arg.startsWith("0x")) { | ||
return txBlock.object((0, import_sui7.normalizeSuiObjectId)(arg)); | ||
return txBlock.object((0, import_sui4.normalizeSuiObjectId)(arg)); | ||
} else if (isMoveVecArg(arg)) { | ||
@@ -352,3 +209,3 @@ const vecType = arg.vecType || void 0; | ||
constructor(transaction) { | ||
this.txBlock = new import_sui8.TransactionBlock(transaction); | ||
this.txBlock = new import_sui5.TransactionBlock(transaction); | ||
} | ||
@@ -535,3 +392,3 @@ //======== override methods of TransactionBlock ============ | ||
arguments: [ | ||
tx.object(import_sui8.SUI_SYSTEM_STATE_OBJECT_ID), | ||
tx.object(import_sui5.SUI_SYSTEM_STATE_OBJECT_ID), | ||
stakeCoin, | ||
@@ -545,2 +402,220 @@ tx.pure(validatorAddr) | ||
// src/libs/suiInteractor/suiInteractor.ts | ||
var import_sui7 = require("@mysten/sui.js"); | ||
// src/libs/suiModel/suiOwnedObject.ts | ||
var import_sui6 = require("@mysten/sui.js"); | ||
var SuiOwnedObject = class { | ||
constructor(param) { | ||
this.objectId = param.objectId; | ||
this.version = param.version; | ||
this.digest = param.digest; | ||
} | ||
/** | ||
* Check if the object is fully initialized. | ||
* So that when it's used as an input, it won't be necessary to fetch from fullnode again. | ||
* Which can save time when sending transactions. | ||
*/ | ||
isFullObject() { | ||
return !!this.version && !!this.digest; | ||
} | ||
asCallArg() { | ||
if (!this.version || !this.digest) { | ||
return this.objectId; | ||
} | ||
return { | ||
Object: { | ||
ImmOrOwned: { | ||
objectId: this.objectId, | ||
version: this.version, | ||
digest: this.digest | ||
} | ||
} | ||
}; | ||
} | ||
/** | ||
* Update object version & digest based on the transaction response. | ||
* @param txResponse | ||
*/ | ||
updateFromTxResponse(txResponse) { | ||
const changes = (0, import_sui6.getObjectChanges)(txResponse); | ||
if (!changes) { | ||
throw new Error("Bad transaction response!"); | ||
} | ||
for (const change of changes) { | ||
if (change.type === "mutated" && change.objectId === this.objectId) { | ||
this.digest = change.digest; | ||
this.version = change.version; | ||
return; | ||
} | ||
} | ||
throw new Error("Could not find object in transaction response!"); | ||
} | ||
}; | ||
// src/libs/suiModel/suiSharedObject.ts | ||
var SuiSharedObject = class { | ||
constructor(param) { | ||
this.objectId = param.objectId; | ||
this.initialSharedVersion = param.initialSharedVersion; | ||
} | ||
asCallArg(mutable = false) { | ||
if (!this.initialSharedVersion) { | ||
return this.objectId; | ||
} | ||
return { | ||
Object: { | ||
Shared: { | ||
objectId: this.objectId, | ||
initialSharedVersion: this.initialSharedVersion, | ||
mutable | ||
} | ||
} | ||
}; | ||
} | ||
}; | ||
// src/libs/suiInteractor/suiInteractor.ts | ||
var SuiInteractor = class { | ||
constructor(fullNodeUrls) { | ||
if (fullNodeUrls.length === 0) | ||
throw new Error("fullNodeUrls must not be empty"); | ||
this.providers = fullNodeUrls.map((url) => new import_sui7.JsonRpcProvider(new import_sui7.Connection({ fullnode: url }))); | ||
this.currentProvider = this.providers[0]; | ||
} | ||
switchToNextProvider() { | ||
const currentProviderIdx = this.providers.indexOf(this.currentProvider); | ||
this.currentProvider = this.providers[(currentProviderIdx + 1) % this.providers.length]; | ||
} | ||
async sendTx(transactionBlock, signature) { | ||
const txResOptions = { | ||
showEvents: true, | ||
showEffects: true, | ||
showObjectChanges: true, | ||
showBalanceChanges: true | ||
}; | ||
const currentProviderIdx = this.providers.indexOf(this.currentProvider); | ||
const providers = [ | ||
...this.providers.slice(currentProviderIdx, this.providers.length), | ||
...this.providers.slice(0, currentProviderIdx) | ||
]; | ||
for (const provider of providers) { | ||
try { | ||
const res = await this.currentProvider.executeTransactionBlock({ | ||
transactionBlock, | ||
signature, | ||
options: txResOptions | ||
}); | ||
this.currentProvider = provider; | ||
return res; | ||
} catch (err) { | ||
console.warn(`Failed to send transaction with fullnode ${provider.connection.fullnode}: ${err}`); | ||
} | ||
} | ||
throw new Error("Failed to send transaction with all fullnodes"); | ||
} | ||
async getObjects(ids) { | ||
const options = { showContent: true, showDisplay: true, showType: true, showOwner: true }; | ||
const currentProviderIdx = this.providers.indexOf(this.currentProvider); | ||
const providers = [ | ||
...this.providers.slice(currentProviderIdx, this.providers.length), | ||
...this.providers.slice(0, currentProviderIdx) | ||
]; | ||
for (const provider of providers) { | ||
try { | ||
const objects = await this.currentProvider.multiGetObjects({ ids, options }); | ||
this.currentProvider = provider; | ||
const parsedObjects = objects.map((object) => { | ||
const objectId = (0, import_sui7.getObjectId)(object); | ||
const objectType = (0, import_sui7.getObjectType)(object); | ||
const objectVersion = (0, import_sui7.getObjectVersion)(object); | ||
const objectDigest = object.data ? object.data.digest : void 0; | ||
const initialSharedVersion = (0, import_sui7.getSharedObjectInitialVersion)(object); | ||
const objectFields = (0, import_sui7.getObjectFields)(object); | ||
const objectDisplay = (0, import_sui7.getObjectDisplay)(object); | ||
return { | ||
objectId, | ||
objectType, | ||
objectVersion, | ||
objectDigest, | ||
objectFields, | ||
objectDisplay, | ||
initialSharedVersion | ||
}; | ||
}); | ||
return parsedObjects; | ||
} catch (err) { | ||
console.warn(`Failed to get objects with fullnode ${provider.connection.fullnode}: ${err}`); | ||
} | ||
} | ||
throw new Error("Failed to get objects with all fullnodes"); | ||
} | ||
async getObject(id) { | ||
const objects = await this.getObjects([id]); | ||
return objects[0]; | ||
} | ||
/** | ||
* @description Update objects in a batch | ||
* @param suiObjects | ||
*/ | ||
async updateObjects(suiObjects) { | ||
const objectIds = suiObjects.map((obj) => obj.objectId); | ||
const objects = await this.getObjects(objectIds); | ||
for (const object of objects) { | ||
const suiObject = suiObjects.find((obj) => obj.objectId === object.objectId); | ||
if (suiObject instanceof SuiSharedObject) { | ||
suiObject.initialSharedVersion = object.initialSharedVersion; | ||
} else if (suiObject instanceof SuiOwnedObject) { | ||
suiObject.version = object.objectVersion; | ||
suiObject.digest = object.objectDigest; | ||
} | ||
} | ||
} | ||
/** | ||
* @description Select coins that add up to the given amount. | ||
* @param addr the address of the owner | ||
* @param amount the amount that is needed for the coin | ||
* @param coinType the coin type, default is '0x2::SUI::SUI' | ||
*/ | ||
async selectCoins(addr, amount, coinType = "0x2::SUI::SUI") { | ||
const coins = await this.currentProvider.getCoins({ owner: addr, coinType }); | ||
const selectedCoins = []; | ||
let totalAmount = 0; | ||
coins.data.sort((a, b) => parseInt(b.balance) - parseInt(a.balance)); | ||
for (const coinData of coins.data) { | ||
selectedCoins.push({ | ||
objectId: coinData.coinObjectId, | ||
digest: coinData.digest, | ||
version: coinData.version | ||
}); | ||
totalAmount = totalAmount + parseInt(coinData.balance); | ||
if (totalAmount >= amount) { | ||
break; | ||
} | ||
} | ||
if (!selectedCoins.length) { | ||
throw new Error("No valid coins found for the transaction."); | ||
} | ||
return selectedCoins; | ||
} | ||
}; | ||
// src/libs/suiInteractor/defaultConfig.ts | ||
var import_sui8 = require("@mysten/sui.js"); | ||
var defaultGasBudget = 10 ** 8; | ||
var getDefaultConnection = (networkType = "devnet") => { | ||
switch (networkType) { | ||
case "localnet": | ||
return import_sui8.localnetConnection; | ||
case "devnet": | ||
return import_sui8.devnetConnection; | ||
case "testnet": | ||
return import_sui8.testnetConnection; | ||
case "mainnet": | ||
return import_sui8.mainnetConnection; | ||
default: | ||
return import_sui8.devnetConnection; | ||
} | ||
}; | ||
// src/suiKit.ts | ||
@@ -558,3 +633,2 @@ var SuiKit = class { | ||
* @param fullnodeUrl, the fullnode url, default is the preconfig fullnode url for the given network type | ||
* @param faucetUrl, the faucet url, default is the preconfig faucet url for the given network type | ||
*/ | ||
@@ -565,11 +639,7 @@ constructor({ | ||
networkType, | ||
fullnodeUrl, | ||
faucetUrl | ||
fullnodeUrls | ||
} = {}) { | ||
this.accountManager = new SuiAccountManager({ mnemonics, secretKey }); | ||
this.rpcProvider = new SuiRpcProvider({ | ||
fullnodeUrl, | ||
faucetUrl, | ||
networkType | ||
}); | ||
fullnodeUrls = fullnodeUrls || [getDefaultConnection(networkType).fullnode]; | ||
this.suiInteractor = new SuiInteractor(fullnodeUrls); | ||
} | ||
@@ -584,3 +654,3 @@ /** | ||
const keyPair = this.accountManager.getKeyPair(derivePathParams); | ||
return new import_sui9.RawSigner(keyPair, this.rpcProvider.provider); | ||
return new import_sui9.RawSigner(keyPair, this.suiInteractor.currentProvider); | ||
} | ||
@@ -605,19 +675,18 @@ /** | ||
provider() { | ||
return this.rpcProvider.provider; | ||
return this.suiInteractor.currentProvider; | ||
} | ||
/** | ||
* Request some SUI from faucet | ||
* @Returns {Promise<boolean>}, true if the request is successful, false otherwise. | ||
*/ | ||
async requestFaucet(derivePathParams) { | ||
const addr = this.accountManager.getAddress(derivePathParams); | ||
return this.rpcProvider.requestFaucet(addr); | ||
} | ||
async getBalance(coinType, derivePathParams) { | ||
const owner = this.accountManager.getAddress(derivePathParams); | ||
return this.rpcProvider.getBalance(owner, coinType); | ||
return this.suiInteractor.currentProvider.getBalance({ owner, coinType }); | ||
} | ||
async getObjects(objectIds) { | ||
return this.rpcProvider.getObjects(objectIds); | ||
return this.suiInteractor.getObjects(objectIds); | ||
} | ||
/** | ||
* @description Update objects in a batch | ||
* @param suiObjects | ||
*/ | ||
async updateObjects(suiObjects) { | ||
return this.suiInteractor.updateObjects(suiObjects); | ||
} | ||
async signTxn(tx, derivePathParams) { | ||
@@ -629,12 +698,4 @@ tx = tx instanceof SuiTxBlock ? tx.txBlock : tx; | ||
async signAndSendTxn(tx, derivePathParams) { | ||
tx = tx instanceof SuiTxBlock ? tx.txBlock : tx; | ||
const signer = this.getSigner(derivePathParams); | ||
return signer.signAndExecuteTransactionBlock({ | ||
transactionBlock: tx, | ||
options: { | ||
showEffects: true, | ||
showEvents: true, | ||
showObjectChanges: true | ||
} | ||
}); | ||
const { transactionBlockBytes, signature } = await this.signTxn(tx, derivePathParams); | ||
return this.suiInteractor.sendTx(transactionBlockBytes, signature); | ||
} | ||
@@ -674,3 +735,3 @@ /** | ||
const totalAmount = amounts.reduce((a, b) => a + b, 0); | ||
const coins = await this.rpcProvider.selectCoins( | ||
const coins = await this.suiInteractor.selectCoins( | ||
owner, | ||
@@ -720,3 +781,3 @@ totalAmount, | ||
owner = owner || this.accountManager.currentAddress; | ||
const coins = await this.rpcProvider.selectCoins(owner, amount, coinType); | ||
const coins = await this.suiInteractor.selectCoins(owner, amount, coinType); | ||
return coins.map((c) => c.objectId); | ||
@@ -744,3 +805,3 @@ } | ||
tx = tx instanceof SuiTxBlock ? tx.txBlock : tx; | ||
return this.rpcProvider.provider.devInspectTransactionBlock({ | ||
return this.suiInteractor.currentProvider.devInspectTransactionBlock({ | ||
transactionBlock: tx, | ||
@@ -757,3 +818,2 @@ sender: this.getAddress(derivePathParams) | ||
SuiKit, | ||
SuiRpcProvider, | ||
SuiTxBlock, | ||
@@ -760,0 +820,0 @@ TransactionBlock |
@@ -5,3 +5,2 @@ export { TransactionBlock, SUI_CLOCK_OBJECT_ID, SUI_SYSTEM_STATE_OBJECT_ID, } from '@mysten/sui.js'; | ||
export { SuiTxBlock } from './libs/suiTxBuilder'; | ||
export { SuiRpcProvider } from './libs/suiRpcProvider'; | ||
export type * from './types'; |
@@ -27,3 +27,2 @@ "use strict"; | ||
SuiKit: () => SuiKit, | ||
SuiRpcProvider: () => SuiRpcProvider, | ||
SuiTxBlock: () => SuiTxBlock, | ||
@@ -154,149 +153,7 @@ TransactionBlock: () => import_sui10.TransactionBlock | ||
// src/libs/suiRpcProvider/index.ts | ||
var import_sui6 = require("@mysten/sui.js"); | ||
// src/libs/suiRpcProvider/faucet.ts | ||
var import_sui4 = require("@mysten/sui.js"); | ||
var import_ts_retry_promise = require("ts-retry-promise"); | ||
var requestFaucet = async (address, provider) => { | ||
console.log("\nRequesting SUI from faucet for address: ", address); | ||
const headers = { | ||
authority: "faucet.testnet.sui.io", | ||
method: "POST", | ||
path: "/gas", | ||
scheme: "https", | ||
accept: "*/*", | ||
"accept-encoding": "gzip, deflate, br", | ||
"accept-language": "zh-CN,zh;q=0.9,en;q=0.8,ja;q=0.7", | ||
"content-length": "105", | ||
"content-type": "application/json", | ||
origin: "chrome-extension://opcgpfmipidbgpenhmajoajpbobppdil", | ||
cookie: '_ga=GA1.1.2092533979.1664032306; sui_io_cookie={"level":["necessary","analytics"],"revision":0,"data":null,"rfc_cookie":false}; _ga_YKP53WJMB0=GS1.1.1680531285.31.0.1680531334.11.0.0; _ga_0GW4F97GFL=GS1.1.1680826187.125.0.1680826187.60.0.0; __cf_bm=6rPjXUwuzUPy4yDlZuXgDj0v7xLPpUd5z0CFGCoN_YI-1680867579-0-AZMhU7/mKUUbUlOa27LmfW6eIFkBkXsPKqYgWjpjWpj2XzDckgUsRu/pxSRGfvXCspn3w7Df+uO1MR/b+XikJU0=; _cfuvid=zjwCXMmu19KBIVo_L9Qbq4TqFXJpophG3.EvFTxqdf4-1680867579342-0-604800000', | ||
"sec-ch-ua": '"Google Chrome";v="111", "Not(A:Brand";v="8", "Chromium";v="111"', | ||
"sec-ch-ua-mobile": "?0", | ||
"sec-ch-ua-platform": "macOS", | ||
"sec-fetch-dest": "empty", | ||
"sec-fetch-mode": "cors", | ||
"sec-fetch-site": "none", | ||
"user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36" | ||
}; | ||
const resp = await (0, import_ts_retry_promise.retry)( | ||
() => provider.requestSuiFromFaucet(address, headers), | ||
{ | ||
backoff: "EXPONENTIAL", | ||
// overall timeout in 60 seconds | ||
timeout: 1e3 * 60, | ||
// skip retry if we hit the rate-limit error | ||
retryIf: (error) => !(error instanceof import_sui4.FaucetRateLimitError), | ||
logger: (msg) => console.warn(`Retry requesting faucet: ${msg}`) | ||
} | ||
); | ||
(0, import_sui4.assert)(resp, import_sui4.FaucetResponse, "Request faucet failed\n"); | ||
console.log("Request faucet success\n"); | ||
}; | ||
// src/libs/suiRpcProvider/defaultChainConfigs.ts | ||
// src/libs/suiTxBuilder/index.ts | ||
var import_sui5 = require("@mysten/sui.js"); | ||
var getDefaultNetworkParams = (networkType = "devnet") => { | ||
switch (networkType) { | ||
case "localnet": | ||
return import_sui5.localnetConnection; | ||
case "devnet": | ||
return import_sui5.devnetConnection; | ||
case "testnet": | ||
return import_sui5.testnetConnection; | ||
case "mainnet": | ||
return import_sui5.mainnetConnection; | ||
default: | ||
return import_sui5.devnetConnection; | ||
} | ||
}; | ||
// src/libs/suiRpcProvider/index.ts | ||
var SuiRpcProvider = class { | ||
/** | ||
* | ||
* @param networkType, 'testnet' | 'mainnet' | 'devnet' | 'localnet', default is 'devnet' | ||
* @param fullnodeUrl, the fullnode url, default is the preconfig fullnode url for the given network type | ||
* @param faucetUrl, the faucet url, default is the preconfig faucet url for the given network type | ||
*/ | ||
constructor({ | ||
fullnodeUrl, | ||
faucetUrl, | ||
networkType | ||
} = {}) { | ||
const defaultNetworkParams = getDefaultNetworkParams( | ||
networkType || "devnet" | ||
); | ||
this.fullnodeUrl = fullnodeUrl || defaultNetworkParams.fullnode; | ||
this.faucetUrl = faucetUrl || defaultNetworkParams.faucet; | ||
const connection = new import_sui6.Connection({ | ||
fullnode: this.fullnodeUrl, | ||
faucet: this.faucetUrl | ||
}); | ||
this.provider = new import_sui6.JsonRpcProvider(connection); | ||
} | ||
/** | ||
* Request some SUI from faucet | ||
* @Returns {Promise<boolean>}, true if the request is successful, false otherwise. | ||
*/ | ||
async requestFaucet(addr) { | ||
return requestFaucet(addr, this.provider); | ||
} | ||
async getBalance(addr, coinType) { | ||
return this.provider.getBalance({ owner: addr, coinType }); | ||
} | ||
async getObjects(ids) { | ||
const options = { showContent: true, showDisplay: true, showType: true }; | ||
const objects = await this.provider.multiGetObjects({ ids, options }); | ||
const parsedObjects = objects.map((object) => { | ||
const objectId = (0, import_sui6.getObjectId)(object); | ||
const objectType = (0, import_sui6.getObjectType)(object); | ||
const objectVersion = (0, import_sui6.getObjectVersion)(object); | ||
const objectFields = (0, import_sui6.getObjectFields)(object); | ||
const objectDisplay = (0, import_sui6.getObjectDisplay)(object); | ||
return { | ||
objectId, | ||
objectType, | ||
objectVersion, | ||
objectFields, | ||
objectDisplay | ||
}; | ||
}); | ||
return parsedObjects; | ||
} | ||
/** | ||
* @description Select coins that add up to the given amount. | ||
* @param addr the address of the owner | ||
* @param amount the amount that is needed for the coin | ||
* @param coinType the coin type, default is '0x2::SUI::SUI' | ||
*/ | ||
async selectCoins(addr, amount, coinType = "0x2::SUI::SUI") { | ||
const coins = await this.provider.getCoins({ owner: addr, coinType }); | ||
const selectedCoins = []; | ||
let totalAmount = 0; | ||
coins.data.sort((a, b) => parseInt(b.balance) - parseInt(a.balance)); | ||
for (const coinData of coins.data) { | ||
selectedCoins.push({ | ||
objectId: coinData.coinObjectId, | ||
digest: coinData.digest, | ||
version: coinData.version | ||
}); | ||
totalAmount = totalAmount + parseInt(coinData.balance); | ||
if (totalAmount >= amount) { | ||
break; | ||
} | ||
} | ||
if (!selectedCoins.length) { | ||
throw new Error("No valid coins found for the transaction."); | ||
} | ||
return selectedCoins; | ||
} | ||
}; | ||
// src/libs/suiTxBuilder/index.ts | ||
var import_sui8 = require("@mysten/sui.js"); | ||
// src/libs/suiTxBuilder/util.ts | ||
var import_sui7 = require("@mysten/sui.js"); | ||
var import_sui4 = require("@mysten/sui.js"); | ||
var getDefaultSuiInputType = (value) => { | ||
@@ -319,3 +176,3 @@ if (typeof value === "string" && value.startsWith("0x")) { | ||
const objects = args.map( | ||
(arg) => typeof arg === "string" ? txBlock.object((0, import_sui7.normalizeSuiObjectId)(arg)) : arg | ||
(arg) => typeof arg === "string" ? txBlock.object((0, import_sui4.normalizeSuiObjectId)(arg)) : arg | ||
); | ||
@@ -336,3 +193,3 @@ return txBlock.makeMoveVec({ objects }); | ||
if (typeof arg === "string" && arg.startsWith("0x")) { | ||
return txBlock.object((0, import_sui7.normalizeSuiObjectId)(arg)); | ||
return txBlock.object((0, import_sui4.normalizeSuiObjectId)(arg)); | ||
} else if (isMoveVecArg(arg)) { | ||
@@ -352,3 +209,3 @@ const vecType = arg.vecType || void 0; | ||
constructor(transaction) { | ||
this.txBlock = new import_sui8.TransactionBlock(transaction); | ||
this.txBlock = new import_sui5.TransactionBlock(transaction); | ||
} | ||
@@ -535,3 +392,3 @@ //======== override methods of TransactionBlock ============ | ||
arguments: [ | ||
tx.object(import_sui8.SUI_SYSTEM_STATE_OBJECT_ID), | ||
tx.object(import_sui5.SUI_SYSTEM_STATE_OBJECT_ID), | ||
stakeCoin, | ||
@@ -545,2 +402,220 @@ tx.pure(validatorAddr) | ||
// src/libs/suiInteractor/suiInteractor.ts | ||
var import_sui7 = require("@mysten/sui.js"); | ||
// src/libs/suiModel/suiOwnedObject.ts | ||
var import_sui6 = require("@mysten/sui.js"); | ||
var SuiOwnedObject = class { | ||
constructor(param) { | ||
this.objectId = param.objectId; | ||
this.version = param.version; | ||
this.digest = param.digest; | ||
} | ||
/** | ||
* Check if the object is fully initialized. | ||
* So that when it's used as an input, it won't be necessary to fetch from fullnode again. | ||
* Which can save time when sending transactions. | ||
*/ | ||
isFullObject() { | ||
return !!this.version && !!this.digest; | ||
} | ||
asCallArg() { | ||
if (!this.version || !this.digest) { | ||
return this.objectId; | ||
} | ||
return { | ||
Object: { | ||
ImmOrOwned: { | ||
objectId: this.objectId, | ||
version: this.version, | ||
digest: this.digest | ||
} | ||
} | ||
}; | ||
} | ||
/** | ||
* Update object version & digest based on the transaction response. | ||
* @param txResponse | ||
*/ | ||
updateFromTxResponse(txResponse) { | ||
const changes = (0, import_sui6.getObjectChanges)(txResponse); | ||
if (!changes) { | ||
throw new Error("Bad transaction response!"); | ||
} | ||
for (const change of changes) { | ||
if (change.type === "mutated" && change.objectId === this.objectId) { | ||
this.digest = change.digest; | ||
this.version = change.version; | ||
return; | ||
} | ||
} | ||
throw new Error("Could not find object in transaction response!"); | ||
} | ||
}; | ||
// src/libs/suiModel/suiSharedObject.ts | ||
var SuiSharedObject = class { | ||
constructor(param) { | ||
this.objectId = param.objectId; | ||
this.initialSharedVersion = param.initialSharedVersion; | ||
} | ||
asCallArg(mutable = false) { | ||
if (!this.initialSharedVersion) { | ||
return this.objectId; | ||
} | ||
return { | ||
Object: { | ||
Shared: { | ||
objectId: this.objectId, | ||
initialSharedVersion: this.initialSharedVersion, | ||
mutable | ||
} | ||
} | ||
}; | ||
} | ||
}; | ||
// src/libs/suiInteractor/suiInteractor.ts | ||
var SuiInteractor = class { | ||
constructor(fullNodeUrls) { | ||
if (fullNodeUrls.length === 0) | ||
throw new Error("fullNodeUrls must not be empty"); | ||
this.providers = fullNodeUrls.map((url) => new import_sui7.JsonRpcProvider(new import_sui7.Connection({ fullnode: url }))); | ||
this.currentProvider = this.providers[0]; | ||
} | ||
switchToNextProvider() { | ||
const currentProviderIdx = this.providers.indexOf(this.currentProvider); | ||
this.currentProvider = this.providers[(currentProviderIdx + 1) % this.providers.length]; | ||
} | ||
async sendTx(transactionBlock, signature) { | ||
const txResOptions = { | ||
showEvents: true, | ||
showEffects: true, | ||
showObjectChanges: true, | ||
showBalanceChanges: true | ||
}; | ||
const currentProviderIdx = this.providers.indexOf(this.currentProvider); | ||
const providers = [ | ||
...this.providers.slice(currentProviderIdx, this.providers.length), | ||
...this.providers.slice(0, currentProviderIdx) | ||
]; | ||
for (const provider of providers) { | ||
try { | ||
const res = await this.currentProvider.executeTransactionBlock({ | ||
transactionBlock, | ||
signature, | ||
options: txResOptions | ||
}); | ||
this.currentProvider = provider; | ||
return res; | ||
} catch (err) { | ||
console.warn(`Failed to send transaction with fullnode ${provider.connection.fullnode}: ${err}`); | ||
} | ||
} | ||
throw new Error("Failed to send transaction with all fullnodes"); | ||
} | ||
async getObjects(ids) { | ||
const options = { showContent: true, showDisplay: true, showType: true, showOwner: true }; | ||
const currentProviderIdx = this.providers.indexOf(this.currentProvider); | ||
const providers = [ | ||
...this.providers.slice(currentProviderIdx, this.providers.length), | ||
...this.providers.slice(0, currentProviderIdx) | ||
]; | ||
for (const provider of providers) { | ||
try { | ||
const objects = await this.currentProvider.multiGetObjects({ ids, options }); | ||
this.currentProvider = provider; | ||
const parsedObjects = objects.map((object) => { | ||
const objectId = (0, import_sui7.getObjectId)(object); | ||
const objectType = (0, import_sui7.getObjectType)(object); | ||
const objectVersion = (0, import_sui7.getObjectVersion)(object); | ||
const objectDigest = object.data ? object.data.digest : void 0; | ||
const initialSharedVersion = (0, import_sui7.getSharedObjectInitialVersion)(object); | ||
const objectFields = (0, import_sui7.getObjectFields)(object); | ||
const objectDisplay = (0, import_sui7.getObjectDisplay)(object); | ||
return { | ||
objectId, | ||
objectType, | ||
objectVersion, | ||
objectDigest, | ||
objectFields, | ||
objectDisplay, | ||
initialSharedVersion | ||
}; | ||
}); | ||
return parsedObjects; | ||
} catch (err) { | ||
console.warn(`Failed to get objects with fullnode ${provider.connection.fullnode}: ${err}`); | ||
} | ||
} | ||
throw new Error("Failed to get objects with all fullnodes"); | ||
} | ||
async getObject(id) { | ||
const objects = await this.getObjects([id]); | ||
return objects[0]; | ||
} | ||
/** | ||
* @description Update objects in a batch | ||
* @param suiObjects | ||
*/ | ||
async updateObjects(suiObjects) { | ||
const objectIds = suiObjects.map((obj) => obj.objectId); | ||
const objects = await this.getObjects(objectIds); | ||
for (const object of objects) { | ||
const suiObject = suiObjects.find((obj) => obj.objectId === object.objectId); | ||
if (suiObject instanceof SuiSharedObject) { | ||
suiObject.initialSharedVersion = object.initialSharedVersion; | ||
} else if (suiObject instanceof SuiOwnedObject) { | ||
suiObject.version = object.objectVersion; | ||
suiObject.digest = object.objectDigest; | ||
} | ||
} | ||
} | ||
/** | ||
* @description Select coins that add up to the given amount. | ||
* @param addr the address of the owner | ||
* @param amount the amount that is needed for the coin | ||
* @param coinType the coin type, default is '0x2::SUI::SUI' | ||
*/ | ||
async selectCoins(addr, amount, coinType = "0x2::SUI::SUI") { | ||
const coins = await this.currentProvider.getCoins({ owner: addr, coinType }); | ||
const selectedCoins = []; | ||
let totalAmount = 0; | ||
coins.data.sort((a, b) => parseInt(b.balance) - parseInt(a.balance)); | ||
for (const coinData of coins.data) { | ||
selectedCoins.push({ | ||
objectId: coinData.coinObjectId, | ||
digest: coinData.digest, | ||
version: coinData.version | ||
}); | ||
totalAmount = totalAmount + parseInt(coinData.balance); | ||
if (totalAmount >= amount) { | ||
break; | ||
} | ||
} | ||
if (!selectedCoins.length) { | ||
throw new Error("No valid coins found for the transaction."); | ||
} | ||
return selectedCoins; | ||
} | ||
}; | ||
// src/libs/suiInteractor/defaultConfig.ts | ||
var import_sui8 = require("@mysten/sui.js"); | ||
var defaultGasBudget = 10 ** 8; | ||
var getDefaultConnection = (networkType = "devnet") => { | ||
switch (networkType) { | ||
case "localnet": | ||
return import_sui8.localnetConnection; | ||
case "devnet": | ||
return import_sui8.devnetConnection; | ||
case "testnet": | ||
return import_sui8.testnetConnection; | ||
case "mainnet": | ||
return import_sui8.mainnetConnection; | ||
default: | ||
return import_sui8.devnetConnection; | ||
} | ||
}; | ||
// src/suiKit.ts | ||
@@ -558,3 +633,2 @@ var SuiKit = class { | ||
* @param fullnodeUrl, the fullnode url, default is the preconfig fullnode url for the given network type | ||
* @param faucetUrl, the faucet url, default is the preconfig faucet url for the given network type | ||
*/ | ||
@@ -565,11 +639,7 @@ constructor({ | ||
networkType, | ||
fullnodeUrl, | ||
faucetUrl | ||
fullnodeUrls | ||
} = {}) { | ||
this.accountManager = new SuiAccountManager({ mnemonics, secretKey }); | ||
this.rpcProvider = new SuiRpcProvider({ | ||
fullnodeUrl, | ||
faucetUrl, | ||
networkType | ||
}); | ||
fullnodeUrls = fullnodeUrls || [getDefaultConnection(networkType).fullnode]; | ||
this.suiInteractor = new SuiInteractor(fullnodeUrls); | ||
} | ||
@@ -584,3 +654,3 @@ /** | ||
const keyPair = this.accountManager.getKeyPair(derivePathParams); | ||
return new import_sui9.RawSigner(keyPair, this.rpcProvider.provider); | ||
return new import_sui9.RawSigner(keyPair, this.suiInteractor.currentProvider); | ||
} | ||
@@ -605,19 +675,18 @@ /** | ||
provider() { | ||
return this.rpcProvider.provider; | ||
return this.suiInteractor.currentProvider; | ||
} | ||
/** | ||
* Request some SUI from faucet | ||
* @Returns {Promise<boolean>}, true if the request is successful, false otherwise. | ||
*/ | ||
async requestFaucet(derivePathParams) { | ||
const addr = this.accountManager.getAddress(derivePathParams); | ||
return this.rpcProvider.requestFaucet(addr); | ||
} | ||
async getBalance(coinType, derivePathParams) { | ||
const owner = this.accountManager.getAddress(derivePathParams); | ||
return this.rpcProvider.getBalance(owner, coinType); | ||
return this.suiInteractor.currentProvider.getBalance({ owner, coinType }); | ||
} | ||
async getObjects(objectIds) { | ||
return this.rpcProvider.getObjects(objectIds); | ||
return this.suiInteractor.getObjects(objectIds); | ||
} | ||
/** | ||
* @description Update objects in a batch | ||
* @param suiObjects | ||
*/ | ||
async updateObjects(suiObjects) { | ||
return this.suiInteractor.updateObjects(suiObjects); | ||
} | ||
async signTxn(tx, derivePathParams) { | ||
@@ -629,12 +698,4 @@ tx = tx instanceof SuiTxBlock ? tx.txBlock : tx; | ||
async signAndSendTxn(tx, derivePathParams) { | ||
tx = tx instanceof SuiTxBlock ? tx.txBlock : tx; | ||
const signer = this.getSigner(derivePathParams); | ||
return signer.signAndExecuteTransactionBlock({ | ||
transactionBlock: tx, | ||
options: { | ||
showEffects: true, | ||
showEvents: true, | ||
showObjectChanges: true | ||
} | ||
}); | ||
const { transactionBlockBytes, signature } = await this.signTxn(tx, derivePathParams); | ||
return this.suiInteractor.sendTx(transactionBlockBytes, signature); | ||
} | ||
@@ -674,3 +735,3 @@ /** | ||
const totalAmount = amounts.reduce((a, b) => a + b, 0); | ||
const coins = await this.rpcProvider.selectCoins( | ||
const coins = await this.suiInteractor.selectCoins( | ||
owner, | ||
@@ -720,3 +781,3 @@ totalAmount, | ||
owner = owner || this.accountManager.currentAddress; | ||
const coins = await this.rpcProvider.selectCoins(owner, amount, coinType); | ||
const coins = await this.suiInteractor.selectCoins(owner, amount, coinType); | ||
return coins.map((c) => c.objectId); | ||
@@ -744,3 +805,3 @@ } | ||
tx = tx instanceof SuiTxBlock ? tx.txBlock : tx; | ||
return this.rpcProvider.provider.devInspectTransactionBlock({ | ||
return this.suiInteractor.currentProvider.devInspectTransactionBlock({ | ||
transactionBlock: tx, | ||
@@ -757,3 +818,2 @@ sender: this.getAddress(derivePathParams) | ||
SuiKit, | ||
SuiRpcProvider, | ||
SuiTxBlock, | ||
@@ -760,0 +820,0 @@ TransactionBlock |
import { Ed25519Keypair } from '@mysten/sui.js'; | ||
import type { AccountMangerParams, DerivePathParams } from './types'; | ||
import type { AccountMangerParams, DerivePathParams } from 'src/types'; | ||
export declare class SuiAccountManager { | ||
@@ -4,0 +4,0 @@ private mnemonics; |
import { Ed25519Keypair } from '@mysten/sui.js'; | ||
import type { DerivePathParams } from './types'; | ||
import type { DerivePathParams } from 'src/types'; | ||
/** | ||
@@ -4,0 +4,0 @@ * @description Get ed25519 derive path for SUI |
import { TransactionBlock, TransactionExpiration, SuiObjectRef, SharedObjectRef, JsonRpcProvider, TransactionType, Transactions, ObjectCallArg } from '@mysten/sui.js'; | ||
import type { SuiTxArg, SuiObjectArg, SuiVecTxArg } from './types'; | ||
import type { SuiTxArg, SuiObjectArg, SuiVecTxArg } from 'src/types'; | ||
export declare class SuiTxBlock { | ||
@@ -4,0 +4,0 @@ txBlock: TransactionBlock; |
import { TransactionArgument, TransactionBlock } from '@mysten/sui.js'; | ||
import { SuiTxArg, SuiInputTypes } from './types'; | ||
import { SuiTxArg, SuiInputTypes } from 'src/types'; | ||
export declare const getDefaultSuiInputType: (value: any) => SuiInputTypes; | ||
@@ -4,0 +4,0 @@ /** |
@@ -1,11 +0,39 @@ | ||
import type { NetworkType as SuiNetworkType } from '../libs/suiRpcProvider/types'; | ||
export type { DerivePathParams } from '../libs/suiAccountManager/types'; | ||
export type { SuiTxArg, SuiVecTxArg, SuiObjectArg, } from '../libs/suiTxBuilder/types'; | ||
export type NetworkType = SuiNetworkType; | ||
import { Infer } from 'superstruct'; | ||
import { DisplayFieldsResponse, ObjectCallArg, ObjectContentFields, SharedObjectRef, SuiObjectRef, TransactionArgument } from "@mysten/sui.js"; | ||
export type AccountMangerParams = { | ||
mnemonics?: string; | ||
secretKey?: string; | ||
}; | ||
export type DerivePathParams = { | ||
accountIndex?: number; | ||
isExternal?: boolean; | ||
addressIndex?: number; | ||
}; | ||
export type NetworkType = 'testnet' | 'mainnet' | 'devnet' | 'localnet'; | ||
export type SuiKitParams = { | ||
mnemonics?: string; | ||
secretKey?: string; | ||
fullnodeUrl?: string; | ||
fullnodeUrls?: string[]; | ||
faucetUrl?: string; | ||
networkType?: NetworkType; | ||
}; | ||
export type ObjectData = { | ||
objectId: string; | ||
objectType: string; | ||
objectVersion: number; | ||
objectDigest: string; | ||
initialSharedVersion?: number; | ||
objectDisplay: DisplayFieldsResponse; | ||
objectFields: ObjectContentFields; | ||
}; | ||
export type SuiTxArg = Infer<typeof TransactionArgument> | Infer<typeof ObjectCallArg> | string | number | bigint | boolean; | ||
export type SuiObjectArg = SharedObjectRef | Infer<typeof SuiObjectRef> | string | Infer<typeof ObjectCallArg> | Infer<typeof TransactionArgument>; | ||
export type SuiVecTxArg = { | ||
value: SuiTxArg[]; | ||
vecType: SuiInputTypes; | ||
} | SuiTxArg[]; | ||
/** | ||
* These are the basics types that can be used in the SUI | ||
*/ | ||
export type SuiBasicTypes = 'address' | 'bool' | 'u8' | 'u16' | 'u32' | 'u64' | 'u128' | 'u256'; | ||
export type SuiInputTypes = 'object' | SuiBasicTypes; |
{ | ||
"name": "@scallop-io/sui-kit", | ||
"version": "0.37.1", | ||
"version": "0.38.0", | ||
"description": "Tookit for interacting with SUI network", | ||
@@ -43,5 +43,3 @@ "keywords": [ | ||
"assert": "^2.0.0", | ||
"colorts": "^0.1.63", | ||
"superstruct": "^1.0.3", | ||
"tmp": "^0.2.1", | ||
"ts-retry-promise": "^0.7.0" | ||
@@ -57,5 +55,5 @@ }, | ||
"@types/node": "^20.3.2", | ||
"@types/tmp": "^0.2.3", | ||
"@typescript-eslint/eslint-plugin": "^5.60.1", | ||
"@typescript-eslint/parser": "^5.60.1", | ||
"@types/tmp": "^0.2.3", | ||
"dotenv": "^16.3.1", | ||
@@ -68,4 +66,4 @@ "eslint": "^8.43.0", | ||
"prettier": "^2.8.8", | ||
"ts-node": "^10.9.1", | ||
"tsconfig-paths": "^4.2.0", | ||
"ts-node": "^10.9.1", | ||
"tsup": "^7.1.0", | ||
@@ -72,0 +70,0 @@ "typedoc": "^0.24.8", |
@@ -9,3 +9,2 @@ export { | ||
export { SuiTxBlock } from './libs/suiTxBuilder'; | ||
export { SuiRpcProvider } from './libs/suiRpcProvider'; | ||
export type * from './types'; |
@@ -5,3 +5,3 @@ import { Ed25519Keypair } from '@mysten/sui.js'; | ||
import { generateMnemonic } from './crypto'; | ||
import type { AccountMangerParams, DerivePathParams } from './types'; | ||
import type { AccountMangerParams, DerivePathParams } from 'src/types'; | ||
@@ -8,0 +8,0 @@ export class SuiAccountManager { |
import { Ed25519Keypair } from '@mysten/sui.js'; | ||
import type { DerivePathParams } from './types'; | ||
import type { DerivePathParams } from 'src/types'; | ||
@@ -4,0 +4,0 @@ /** |
@@ -13,3 +13,3 @@ import { | ||
import { convertArgs } from './util'; | ||
import type { SuiTxArg, SuiObjectArg, SuiVecTxArg } from './types'; | ||
import type { SuiTxArg, SuiObjectArg, SuiVecTxArg } from 'src/types'; | ||
@@ -16,0 +16,0 @@ export class SuiTxBlock { |
@@ -6,3 +6,3 @@ import { | ||
} from '@mysten/sui.js'; | ||
import { SuiTxArg, SuiInputTypes } from './types'; | ||
import { SuiTxArg, SuiInputTypes } from 'src/types'; | ||
@@ -9,0 +9,0 @@ export const getDefaultSuiInputType = (value: any): SuiInputTypes => { |
/** | ||
* @file src.ts | ||
* @description This file is used to aggregate the tools that used to interact with SUI network. | ||
* @author IceFox | ||
* @version 0.1.0 | ||
*/ | ||
@@ -14,4 +11,5 @@ import { | ||
import { SuiAccountManager } from './libs/suiAccountManager'; | ||
import { SuiRpcProvider } from './libs/suiRpcProvider'; | ||
import { SuiTxBlock } from './libs/suiTxBuilder'; | ||
import { SuiInteractor, getDefaultConnection } from './libs/suiInteractor'; | ||
import { SuiSharedObject, SuiOwnedObject } from './libs/suiModel'; | ||
import { SuiKitParams, DerivePathParams, SuiTxArg, SuiVecTxArg } from './types'; | ||
@@ -25,3 +23,3 @@ | ||
public accountManager: SuiAccountManager; | ||
public rpcProvider: SuiRpcProvider; | ||
public suiInteractor: SuiInteractor; | ||
@@ -38,3 +36,2 @@ /** | ||
* @param fullnodeUrl, the fullnode url, default is the preconfig fullnode url for the given network type | ||
* @param faucetUrl, the faucet url, default is the preconfig faucet url for the given network type | ||
*/ | ||
@@ -45,4 +42,3 @@ constructor({ | ||
networkType, | ||
fullnodeUrl, | ||
faucetUrl, | ||
fullnodeUrls, | ||
}: SuiKitParams = {}) { | ||
@@ -52,7 +48,4 @@ // Init the account manager | ||
// Init the rpc provider | ||
this.rpcProvider = new SuiRpcProvider({ | ||
fullnodeUrl, | ||
faucetUrl, | ||
networkType, | ||
}); | ||
fullnodeUrls = fullnodeUrls || [getDefaultConnection(networkType).fullnode]; | ||
this.suiInteractor = new SuiInteractor(fullnodeUrls); | ||
} | ||
@@ -68,3 +61,3 @@ | ||
const keyPair = this.accountManager.getKeyPair(derivePathParams); | ||
return new RawSigner(keyPair, this.rpcProvider.provider); | ||
return new RawSigner(keyPair, this.suiInteractor.currentProvider); | ||
} | ||
@@ -92,23 +85,22 @@ | ||
provider() { | ||
return this.rpcProvider.provider; | ||
return this.suiInteractor.currentProvider; | ||
} | ||
/** | ||
* Request some SUI from faucet | ||
* @Returns {Promise<boolean>}, true if the request is successful, false otherwise. | ||
*/ | ||
async requestFaucet(derivePathParams?: DerivePathParams) { | ||
const addr = this.accountManager.getAddress(derivePathParams); | ||
return this.rpcProvider.requestFaucet(addr); | ||
} | ||
async getBalance(coinType?: string, derivePathParams?: DerivePathParams) { | ||
const owner = this.accountManager.getAddress(derivePathParams); | ||
return this.rpcProvider.getBalance(owner, coinType); | ||
return this.suiInteractor.currentProvider.getBalance({ owner, coinType }); | ||
} | ||
async getObjects(objectIds: string[]) { | ||
return this.rpcProvider.getObjects(objectIds); | ||
return this.suiInteractor.getObjects(objectIds); | ||
} | ||
/** | ||
* @description Update objects in a batch | ||
* @param suiObjects | ||
*/ | ||
async updateObjects(suiObjects: (SuiSharedObject | SuiOwnedObject)[]) { | ||
return this.suiInteractor.updateObjects(suiObjects); | ||
} | ||
async signTxn( | ||
@@ -127,12 +119,4 @@ tx: Uint8Array | TransactionBlock | SuiTxBlock, | ||
): Promise<SuiTransactionBlockResponse> { | ||
tx = tx instanceof SuiTxBlock ? tx.txBlock : tx; | ||
const signer = this.getSigner(derivePathParams); | ||
return signer.signAndExecuteTransactionBlock({ | ||
transactionBlock: tx, | ||
options: { | ||
showEffects: true, | ||
showEvents: true, | ||
showObjectChanges: true, | ||
}, | ||
}); | ||
const { transactionBlockBytes, signature } = await this.signTxn(tx, derivePathParams); | ||
return this.suiInteractor.sendTx(transactionBlockBytes, signature); | ||
} | ||
@@ -188,3 +172,3 @@ | ||
const totalAmount = amounts.reduce((a, b) => a + b, 0); | ||
const coins = await this.rpcProvider.selectCoins( | ||
const coins = await this.suiInteractor.selectCoins( | ||
owner, | ||
@@ -256,3 +240,3 @@ totalAmount, | ||
owner = owner || this.accountManager.currentAddress; | ||
const coins = await this.rpcProvider.selectCoins(owner, amount, coinType); | ||
const coins = await this.suiInteractor.selectCoins(owner, amount, coinType); | ||
return coins.map((c) => c.objectId); | ||
@@ -289,3 +273,3 @@ } | ||
tx = tx instanceof SuiTxBlock ? tx.txBlock : tx; | ||
return this.rpcProvider.provider.devInspectTransactionBlock({ | ||
return this.suiInteractor.currentProvider.devInspectTransactionBlock({ | ||
transactionBlock: tx, | ||
@@ -292,0 +276,0 @@ sender: this.getAddress(derivePathParams), |
@@ -1,17 +0,73 @@ | ||
import type { NetworkType as SuiNetworkType } from '../libs/suiRpcProvider/types'; | ||
import { Infer } from 'superstruct'; | ||
import { | ||
DisplayFieldsResponse, ObjectCallArg, | ||
ObjectContentFields, | ||
SharedObjectRef, | ||
SuiObjectRef, | ||
TransactionArgument | ||
} from "@mysten/sui.js"; | ||
export type { DerivePathParams } from '../libs/suiAccountManager/types'; | ||
export type { | ||
SuiTxArg, | ||
SuiVecTxArg, | ||
SuiObjectArg, | ||
} from '../libs/suiTxBuilder/types'; | ||
export type AccountMangerParams = { | ||
mnemonics?: string; | ||
secretKey?: string; | ||
}; | ||
export type NetworkType = SuiNetworkType; | ||
export type DerivePathParams = { | ||
accountIndex?: number; | ||
isExternal?: boolean; | ||
addressIndex?: number; | ||
}; | ||
export type NetworkType = 'testnet' | 'mainnet' | 'devnet' | 'localnet'; | ||
export type SuiKitParams = { | ||
mnemonics?: string; | ||
secretKey?: string; | ||
fullnodeUrl?: string; | ||
fullnodeUrls?: string[]; | ||
faucetUrl?: string; | ||
networkType?: NetworkType; | ||
}; | ||
export type ObjectData = { | ||
objectId: string; | ||
objectType: string; | ||
objectVersion: number; | ||
objectDigest: string; | ||
initialSharedVersion?: number; | ||
objectDisplay: DisplayFieldsResponse; | ||
objectFields: ObjectContentFields; | ||
}; | ||
export type SuiTxArg = | ||
| Infer<typeof TransactionArgument> | ||
| Infer<typeof ObjectCallArg> | ||
| string | ||
| number | ||
| bigint | ||
| boolean; | ||
export type SuiObjectArg = | ||
| SharedObjectRef | ||
| Infer<typeof SuiObjectRef> | ||
| string | ||
| Infer<typeof ObjectCallArg> | ||
| Infer<typeof TransactionArgument>; | ||
export type SuiVecTxArg = | ||
| { value: SuiTxArg[]; vecType: SuiInputTypes } | ||
| SuiTxArg[]; | ||
/** | ||
* These are the basics types that can be used in the SUI | ||
*/ | ||
export type SuiBasicTypes = | ||
| 'address' | ||
| 'bool' | ||
| 'u8' | ||
| 'u16' | ||
| 'u32' | ||
| 'u64' | ||
| 'u128' | ||
| 'u256'; | ||
export type SuiInputTypes = 'object' | SuiBasicTypes; |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
357756
6
6785
- Removedcolorts@^0.1.63
- Removedtmp@^0.2.1
- Removedcolorts@0.1.63(transitive)
- Removedtmp@0.2.3(transitive)