@scallop-io/sui-kit 1.4.0-alpha.1 → 1.4.0-alpha.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -185,7 +185,7 @@ const pkgId =
185
185
  (async () => {
186
186
  const mnemonics = process.env.MNEMONICS;
187
187
  const suiKit = new SuiKit({ mnemonics });
188
- const sender = suiKit.currentAddress();
188
+ const sender = suiKit.currentAddress;
189
189
 
190
190
  const tx = new SuiTxBlock();
191
191
  // 1. Make a flash loan for coinB
package/dist/index.js CHANGED
@@ -10,13 +10,13 @@ var cryptography = require('@mysten/sui/cryptography');
10
10
  var bcs = require('@mysten/bcs');
11
11
  var multisig = require('@mysten/sui/multisig');
12
12
 
13
- var F=(r={})=>{let{accountIndex:t=0,isExternal:e=!1,addressIndex:i=0}=r;return `m/44'/784'/${t}'/${e?1:0}'/${i}'`},b=(r,t={})=>{let e=F(t);return ed25519.Ed25519Keypair.deriveKeypair(r,e)};var G=r=>/^0x[0-9a-fA-F]+$|^[0-9a-fA-F]+$/.test(r),z=r=>/^[a-zA-Z0-9+/]+={0,2}$/g.test(r),W=r=>{if(!r)throw new Error("cannot parse empty string to Uint8Array");let t=r.replace("0x","").match(/.{1,2}/g)?.map(e=>parseInt(e,16));if(!t||t.length===0)throw new Error(`Unable to parse HEX: ${r}`);return Uint8Array.from(t)},k=r=>{if(G(r))return W(r);if(z(r))return utils.fromB64(r);throw new Error("The string is not a valid hex or base64 string.")},j=32,Z=64,T=r=>{if(r.length===Z)r=r.slice(0,j);else {if(r.length===j+1&&r[0]===0)return r.slice(1);if(r.length===j)return r}throw new Error("invalid secret key")};var w=(r=24)=>bip39.generateMnemonic(english.wordlist,r===12?128:256);var S=class{constructor({mnemonics:t,secretKey:e}={}){this.mnemonics=t||"",this.secretKey=e||"",!this.mnemonics&&!this.secretKey&&(this.mnemonics=w(24)),this.currentKeyPair=this.secretKey?this.parseSecretKey(this.secretKey):b(this.mnemonics),this.currentAddress=this.currentKeyPair.getPublicKey().toSuiAddress();}parseSecretKey(t){if(t.startsWith(cryptography.SUI_PRIVATE_KEY_PREFIX)){let{secretKey:e}=cryptography.decodeSuiPrivateKey(t);return ed25519.Ed25519Keypair.fromSecretKey(T(e))}return ed25519.Ed25519Keypair.fromSecretKey(T(k(t)))}getKeyPair(t){return !t||!this.mnemonics?this.currentKeyPair:b(this.mnemonics,t)}getAddress(t){return !t||!this.mnemonics?this.currentAddress:b(this.mnemonics,t).getPublicKey().toSuiAddress()}switchAccount(t){this.mnemonics&&(this.currentKeyPair=b(this.mnemonics,t),this.currentAddress=this.currentKeyPair.getPublicKey().toSuiAddress());}};var it=r=>typeof r=="string"&&utils.isValidSuiObjectId(r)?"object":typeof r=="number"||typeof r=="bigint"?"u64":typeof r=="boolean"?"bool":void 0;function R(r){return typeof r=="number"||typeof r=="bigint"||typeof r=="string"&&!utils.isValidSuiAddress(r)&&!isNaN(Number(r))}function nt(r){return typeof r=="object"&&"vecType"in r&&"value"in r?!0:!!Array.isArray(r)}function st(r){return typeof r=="object"&&"digest"in r&&"version"in r&&"objectId"in r}function ot(r){return typeof r=="object"&&"objectId"in r&&"initialSharedVersion"in r&&"mutable"in r}function I(r,t,e){if(t.length===0)throw new Error("Transaction builder error: Empty array is not allowed");let i=it(t[0]),n=/^vector<(.+)>$/,s=/^([^:]+)::([^:]+)::([^<]+)(<(.+)>)?/;if(e=e||i,e==="object"){let o=t.map(a=>typeof a=="string"&&utils.isValidSuiObjectId(a)?r.object(utils.normalizeSuiObjectId(a)):l(r,a));return r.makeMoveVec({elements:o})}else if(typeof e=="string"&&!n.test(e)&&!s.test(e)){let o=transactions.getPureBcsSchema(e);return r.pure(bcs.bcs.vector(o).serialize(t))}else {let o=t.map(a=>l(r,a));return r.makeMoveVec({elements:o,type:e})}}function f(r,t){return t.map(e=>e instanceof bcs.SerializedBcs||bcs.isSerializedBcs(e)?r.pure(e):nt(e)?"vecType"in e?I(r,e.value,e.vecType):I(r,e):R(e)?m(r,[e])[0]:l(r,e))}function p(r,t){return typeof t=="string"&&utils.isValidSuiAddress(t)?r.pure.address(utils.normalizeSuiAddress(t)):f(r,[t])[0]}function l(r,t){if(typeof t=="string")return r.object(t);if(st(t))return r.objectRef(t);if(ot(t))return r.sharedObjectRef(t);if("Object"in t){if("ImmOrOwnedObject"in t.Object)return r.object(transactions.Inputs.ObjectRef(t.Object.ImmOrOwnedObject));if("SharedObject"in t.Object)return r.object(transactions.Inputs.SharedObjectRef(t.Object.SharedObject));throw new Error("Invalid argument type")}if(typeof t=="function"||"GasCoin"in t||"Input"in t||"Result"in t||"NestedResult"in t)return t;throw new Error("Invalid argument type")}function m(r,t){return t.map(e=>R(e)?r.pure.u64(e):f(r,[e])[0])}var c=class{constructor(t){this.txBlock=t?transactions.Transaction.from(t):new transactions.Transaction;}get gas(){return this.txBlock.gas}get blockData(){return this.txBlock.blockData}get getData(){return this.txBlock.getData()}address(t){return this.txBlock.pure.address(t)}get pure(){return this.txBlock.pure}object(t){return this.txBlock.object(t)}objectRef(t){return this.txBlock.objectRef(t)}sharedObjectRef(t){return this.txBlock.sharedObjectRef(t)}setSender(t){return this.txBlock.setSender(t)}setSenderIfNotSet(t){return this.txBlock.setSenderIfNotSet(t)}setExpiration(t){return this.txBlock.setExpiration(t)}setGasPrice(t){return this.txBlock.setGasPrice(t)}setGasBudget(t){return this.txBlock.setGasBudget(t)}setGasOwner(t){return this.txBlock.setGasOwner(t)}setGasPayment(t){return this.txBlock.setGasPayment(t)}serialize(){return this.txBlock.serialize()}toJSON(){return this.txBlock.toJSON()}sign(t){return this.txBlock.sign(t)}build(t={}){return this.txBlock.build(t)}getDigest(t={}){return this.txBlock.getDigest(t)}add(...t){return this.txBlock.add(...t)}publish({modules:t,dependencies:e}){return this.txBlock.publish({modules:t,dependencies:e})}upgrade(...t){return this.txBlock.upgrade(...t)}makeMoveVec(...t){return this.txBlock.makeMoveVec(...t)}transferObjects(t,e){return this.txBlock.transferObjects(t.map(i=>l(this.txBlock,i)),p(this.txBlock,e))}splitCoins(t,e){let i=this.txBlock.splitCoins(l(this.txBlock,t),m(this.txBlock,e));return e.map((n,s)=>i[s])}mergeCoins(t,e){let i=l(this.txBlock,t),n=e.map(s=>l(this.txBlock,s));return this.txBlock.mergeCoins(i,n)}moveCall(t,e=[],i=[]){let n=/(?<package>[a-zA-Z0-9]+)::(?<module>[a-zA-Z0-9_]+)::(?<function>[a-zA-Z0-9_]+)/;if(t.match(n)===null)throw new Error("Invalid target format. Expected `${string}::${string}::${string}`");let o=f(this.txBlock,e);return this.txBlock.moveCall({target:t,arguments:o,typeArguments:i})}transferSuiToMany(t,e){if(t.length!==e.length)throw new Error("transferSuiToMany: recipients.length !== amounts.length");let i=this.txBlock.splitCoins(this.txBlock.gas,m(this.txBlock,e));return t.map(s=>p(this.txBlock,s)).forEach((s,o)=>{this.txBlock.transferObjects([i[o]],s);}),this}transferSui(t,e){return this.transferSuiToMany([t],[e])}takeAmountFromCoins(t,e){let i=t.map(o=>l(this.txBlock,o)),n=i[0];t.length>1&&this.txBlock.mergeCoins(n,i.slice(1));let[s]=this.txBlock.splitCoins(n,m(this.txBlock,[e]));return [s,n]}splitSUIFromGas(t){return this.txBlock.splitCoins(this.txBlock.gas,m(this.txBlock,t))}splitMultiCoins(t,e){let i=t.map(o=>l(this.txBlock,o)),n=i[0];return t.length>1&&this.txBlock.mergeCoins(n,i.slice(1)),{splitedCoins:this.txBlock.splitCoins(n,m(this.txBlock,e)),mergedCoin:n}}transferCoinToMany(t,e,i,n){if(i.length!==n.length)throw new Error("transferSuiToMany: recipients.length !== amounts.length");let s=t.map(u=>l(this.txBlock,u)),{splitedCoins:o,mergedCoin:a}=this.splitMultiCoins(s,m(this.txBlock,n));return i.map(u=>p(this.txBlock,u)).forEach((u,d)=>{this.txBlock.transferObjects([o[d]],u);}),this.txBlock.transferObjects([a],p(this.txBlock,e)),this}transferCoin(t,e,i,n){return this.transferCoinToMany(t,e,[i],[n])}stakeSui(t,e){let[i]=this.txBlock.splitCoins(this.txBlock.gas,m(this.txBlock,[t]));return this.txBlock.moveCall({target:"0x3::sui_system::request_add_stake",arguments:f(this.txBlock,[this.txBlock.object(utils.SUI_SYSTEM_STATE_OBJECT_ID),i,p(this.txBlock,e)])})}};var y=class{constructor(t){this.objectId=t.objectId,this.version=t.version,this.digest=t.digest;}isFullObject(){return !!this.version&&!!this.digest}asCallArg(){return !this.version||!this.digest?this.objectId:{$kind:"Object",Object:{$kind:"ImmOrOwnedObject",ImmOrOwnedObject:{objectId:this.objectId,version:this.version,digest:this.digest}}}}updateFromTxResponse(t){let e=t.objectChanges;if(!e)throw new Error("Bad transaction response!");for(let i of e)if(i.type==="mutated"&&i.objectId===this.objectId){this.digest=i.digest,this.version=i.version;return}throw new Error("Could not find object in transaction response!")}};var A=class{constructor(t){this.objectId=t.objectId,this.initialSharedVersion=t.initialSharedVersion;}asCallArg(t=!1){return this.initialSharedVersion?{$kind:"Object",Object:{$kind:"SharedObject",SharedObject:{objectId:this.objectId,initialSharedVersion:this.initialSharedVersion,mutable:t}}}:this.objectId}};var P=r=>new Promise(t=>setTimeout(t,r));var g=class{constructor(t){this.clients=[];this.fullNodes=[];"fullnodeUrls"in t?(this.fullNodes=t.fullnodeUrls??[client.getFullnodeUrl("mainnet")],this.clients=this.fullNodes.map(e=>new client.SuiClient({url:e}))):"suiClients"in t&&t.suiClients?this.clients=t.suiClients:this.clients=[new client.SuiClient({url:client.getFullnodeUrl("mainnet")})],this.currentClient=this.clients[0];}switchToNextClient(){let t=this.clients.indexOf(this.currentClient);this.currentClient=this.clients[(t+1)%this.clients.length];}async sendTx(t,e){let i={showEvents:!0,showEffects:!0,showRawEffects:!0,showObjectChanges:!0,showBalanceChanges:!0};for(let n in this.clients)try{return await this.clients[n].executeTransactionBlock({transactionBlock:t,signature:e,options:i})}catch(s){console.warn(`Failed to send transaction with fullnode ${this.fullNodes[n]}: ${s}`),await P(2e3);}throw new Error("Failed to send transaction with all fullnodes")}async dryRunTx(t){for(let e in this.clients)try{return await this.clients[e].dryRunTransactionBlock({transactionBlock:t})}catch(i){console.warn(`Failed to dry run transaction with fullnode ${this.fullNodes[e]}: ${i}`),await P(2e3);}throw new Error("Failed to dry run transaction with all fullnodes")}async getObjects(t,e){let i=e??{showContent:!0,showDisplay:!0,showType:!0,showOwner:!0};for(let n in this.clients)try{return (await this.clients[n].multiGetObjects({ids:t,options:i})).map(a=>a.data).filter(a=>a!=null)}catch(s){await P(2e3),console.warn(`Failed to get objects with fullnode ${this.fullNodes[n]}: ${s}`);}throw new Error("Failed to get objects with all fullnodes")}async getObject(t,e){return (await this.getObjects([t],e))[0]}async updateObjects(t){let e=t.map(n=>n.objectId),i=await this.getObjects(e);for(let n of i){let s=t.find(o=>o.objectId===n?.objectId);s instanceof A?n.owner&&typeof n.owner=="object"&&"Shared"in n.owner?s.initialSharedVersion=n.owner.Shared.initial_shared_version:s.initialSharedVersion=void 0:s instanceof y&&(s.version=n?.version,s.digest=n?.digest);}}async selectCoins(t,e,i="0x2::SUI::SUI"){let n=[],s=0,o=!0,a=null;for(;o&&s<e;){let h=await this.currentClient.getCoins({owner:t,coinType:i,cursor:a});h.data.sort((u,d)=>parseInt(d.balance)-parseInt(u.balance));for(let u of h.data)if(n.push({objectId:u.coinObjectId,digest:u.digest,version:u.version,balance:u.balance}),s=s+parseInt(u.balance),s>=e)break;a=h.nextCursor,o=h.hasNextPage;}if(!n.length)throw new Error("No valid coins found for the transaction.");return n}};var O=class{constructor(t){let{mnemonics:e,secretKey:i,networkType:n}=t;this.accountManager=new S({mnemonics:e,secretKey:i});let s;"fullnodeUrls"in t?s={fullnodeUrls:t.fullnodeUrls}:"suiClients"in t?s={suiClients:t.suiClients}:s={fullnodeUrls:[client.getFullnodeUrl(n??"mainnet")]},this.suiInteractor=new g(s);}createTxBlock(){let t=new c;return t.setSender(this.accountManager.currentAddress),t}getKeypair(t){return this.accountManager.getKeyPair(t)}switchAccount(t){this.accountManager.switchAccount(t);}getAddress(t){return this.accountManager.getAddress(t)}currentAddress(){return this.accountManager.currentAddress}async getBalance(t,e){let i=this.accountManager.getAddress(e);return this.suiInteractor.currentClient.getBalance({owner:i,coinType:t})}client(){return this.suiInteractor.currentClient}async getObjects(t,e){return this.suiInteractor.getObjects(t,e)}async updateObjects(t){return this.suiInteractor.updateObjects(t)}async signTxn(t,e){t instanceof c&&t.setSender(this.getAddress(e));let i=t instanceof c?t.txBlock:t,n=i instanceof transactions.Transaction?await i.build({client:this.client()}):i;return await this.getKeypair(e).signTransaction(n)}async signAndSendTxn(t,e){let{bytes:i,signature:n}=await this.signTxn(t,e);return this.suiInteractor.sendTx(i,n)}async dryRunTxn(t,e){t instanceof c&&t.setSender(this.getAddress(e));let i=t instanceof c?t.txBlock:t,n=i instanceof transactions.Transaction?await i.build({client:this.client()}):i;return this.suiInteractor.dryRunTx(n)}async transferSui(t,e,i=!0,n){let s=new c;return s.transferSui(t,e),i?await this.signAndSendTxn(s,n):s}async transferSuiToMany(t,e,i=!0,n){let s=new c;return s.transferSuiToMany(t,e),i?await this.signAndSendTxn(s,n):s}async transferCoinToMany(t,e,i,n=!0,s){let o=new c,a=this.accountManager.getAddress(s),h=e.reduce((d,$)=>d+$,0),u=await this.suiInteractor.selectCoins(a,h,i);return o.transferCoinToMany(u.map(d=>d.objectId),a,t,e),n?await this.signAndSendTxn(o,s):o}async transferCoin(t,e,i,n=!0,s){return this.transferCoinToMany([t],[e],i,n,s)}async transferObjects(t,e,i=!0,n){let s=new c;return s.transferObjects(t,e),i?await this.signAndSendTxn(s,n):s}async moveCall(t){let{target:e,arguments:i=[],typeArguments:n=[],derivePathParams:s}=t,o=new c;return o.moveCall(e,i,n),this.signAndSendTxn(o,s)}async selectCoinsWithAmount(t,e,i){return i=i||this.accountManager.currentAddress,await this.suiInteractor.selectCoins(i,t,e)}async stakeSui(t,e,i=!0,n){let s=new c;return s.stakeSui(t,e),i?await this.signAndSendTxn(s,n):s}async inspectTxn(t,e){let i=t instanceof c?t.txBlock:t;return this.suiInteractor.currentClient.devInspectTransactionBlock({transactionBlock:i,sender:this.getAddress(e)})}};function U(r){let t=utils.fromB64(r);if(t.length!==32&&t.length!==33)throw "invalid pubkey length";return t=t.length===33?t.slice(1):t,new ed25519.Ed25519PublicKey(t)}var x=class r{constructor(t,e){this.pksWeightPairs=t,this.threshold=e,this.multiSigPublicKey=multisig.MultiSigPublicKey.fromPublicKeys({threshold:this.threshold,publicKeys:this.pksWeightPairs});}static fromRawEd25519PublicKeys(t,e,i){let n=t.map((s,o)=>({publicKey:U(s),weight:e[o]}));return new r(n,i)}multiSigAddress(){return this.multiSigPublicKey.toSuiAddress()}combinePartialSigs(t){return this.multiSigPublicKey.combinePartialSignatures(t)}};
13
+ var F=(r={})=>{let{accountIndex:t=0,isExternal:e=!1,addressIndex:i=0}=r;return `m/44'/784'/${t}'/${e?1:0}'/${i}'`},S=(r,t={})=>{let e=F(t);return ed25519.Ed25519Keypair.deriveKeypair(r,e)};var G=r=>/^0x[0-9a-fA-F]+$|^[0-9a-fA-F]+$/.test(r),W=r=>/^[a-zA-Z0-9+/]+={0,2}$/g.test(r),Z=r=>{if(!r)throw new Error("cannot parse empty string to Uint8Array");let t=r.replace("0x","").match(/.{1,2}/g)?.map(e=>parseInt(e,16));if(!t||t.length===0)throw new Error(`Unable to parse HEX: ${r}`);return Uint8Array.from(t)},B=r=>{if(G(r))return Z(r);if(W(r))return utils.fromB64(r);throw new Error("The string is not a valid hex or base64 string.")},T=32,X=64,O=r=>{if(r.length===X)r=r.slice(0,T);else {if(r.length===T+1&&r[0]===0)return r.slice(1);if(r.length===T)return r}throw new Error("invalid secret key")};var v=(r=24)=>bip39.generateMnemonic(english.wordlist,r===12?128:256);var f=class{constructor({mnemonics:t,secretKey:e}={}){this.mnemonics=t||"",this.secretKey=e||"",!this.mnemonics&&!this.secretKey&&(this.mnemonics=v(24)),this.currentKeyPair=this.secretKey?this.parseSecretKey(this.secretKey):S(this.mnemonics),this.currentAddress=this.currentKeyPair.getPublicKey().toSuiAddress();}parseSecretKey(t){if(t.startsWith(cryptography.SUI_PRIVATE_KEY_PREFIX)){let{secretKey:e}=cryptography.decodeSuiPrivateKey(t);return ed25519.Ed25519Keypair.fromSecretKey(O(e))}return ed25519.Ed25519Keypair.fromSecretKey(O(B(t)))}getKeyPair(t){return !t||!this.mnemonics?this.currentKeyPair:S(this.mnemonics,t)}getAddress(t){return !t||!this.mnemonics?this.currentAddress:S(this.mnemonics,t).getPublicKey().toSuiAddress()}switchAccount(t){this.mnemonics&&(this.currentKeyPair=S(this.mnemonics,t),this.currentAddress=this.currentKeyPair.getPublicKey().toSuiAddress());}};var nt=r=>typeof r=="string"&&utils.isValidSuiObjectId(r)?"object":typeof r=="number"||typeof r=="bigint"?"u64":typeof r=="boolean"?"bool":void 0;function E(r){return typeof r=="number"||typeof r=="bigint"||typeof r=="string"&&!utils.isValidSuiAddress(r)&&!isNaN(Number(r))}function st(r){return typeof r=="object"&&"vecType"in r&&"value"in r?!0:!!Array.isArray(r)}function ot(r){return typeof r=="object"&&"digest"in r&&"version"in r&&"objectId"in r}function at(r){return typeof r=="object"&&"objectId"in r&&"initialSharedVersion"in r&&"mutable"in r}function K(r,t,e){if(t.length===0)throw new Error("Transaction builder error: Empty array is not allowed");let i=nt(t[0]),n=/^vector<(.+)>$/,s=/^([^:]+)::([^:]+)::([^<]+)(<(.+)>)?/;if(e=e||i,e==="object"){let o=t.map(c=>typeof c=="string"&&utils.isValidSuiObjectId(c)?r.object(utils.normalizeSuiObjectId(c)):l(r,c));return r.makeMoveVec({elements:o})}else if(typeof e=="string"&&!n.test(e)&&!s.test(e)){let o=transactions.getPureBcsSchema(e);return r.pure(bcs.bcs.vector(o).serialize(t))}else {let o=t.map(c=>l(r,c));return r.makeMoveVec({elements:o,type:e})}}function y(r,t){return t.map(e=>e instanceof bcs.SerializedBcs||bcs.isSerializedBcs(e)?r.pure(e):st(e)?"vecType"in e?K(r,e.value,e.vecType):K(r,e):E(e)?d(r,[e])[0]:l(r,e))}function p(r,t){return typeof t=="string"&&utils.isValidSuiAddress(t)?r.pure.address(utils.normalizeSuiAddress(t)):y(r,[t])[0]}function l(r,t){if(typeof t=="string")return r.object(t);if(ot(t))return r.objectRef(t);if(at(t))return r.sharedObjectRef(t);if("Object"in t){if("ImmOrOwnedObject"in t.Object)return r.object(transactions.Inputs.ObjectRef(t.Object.ImmOrOwnedObject));if("SharedObject"in t.Object)return r.object(transactions.Inputs.SharedObjectRef(t.Object.SharedObject));throw new Error("Invalid argument type")}if(typeof t=="function"||"GasCoin"in t||"Input"in t||"Result"in t||"NestedResult"in t)return t;throw new Error("Invalid argument type")}function d(r,t){return t.map(e=>E(e)?r.pure.u64(e):y(r,[e])[0])}var u=class{constructor(t){this.txBlock=t?transactions.Transaction.from(t):new transactions.Transaction;}get gas(){return this.txBlock.gas}get blockData(){return this.txBlock.blockData}get getData(){return this.txBlock.getData()}address(t){return this.txBlock.pure.address(t)}get pure(){return this.txBlock.pure}object(t){return this.txBlock.object(t)}objectRef(t){return this.txBlock.objectRef(t)}sharedObjectRef(t){return this.txBlock.sharedObjectRef(t)}setSender(t){return this.txBlock.setSender(t)}setSenderIfNotSet(t){return this.txBlock.setSenderIfNotSet(t)}setExpiration(t){return this.txBlock.setExpiration(t)}setGasPrice(t){return this.txBlock.setGasPrice(t)}setGasBudget(t){return this.txBlock.setGasBudget(t)}setGasOwner(t){return this.txBlock.setGasOwner(t)}setGasPayment(t){return this.txBlock.setGasPayment(t)}serialize(){return this.txBlock.serialize()}toJSON(){return this.txBlock.toJSON()}sign(t){return this.txBlock.sign(t)}build(t={}){return this.txBlock.build(t)}getDigest(t={}){return this.txBlock.getDigest(t)}add(...t){return this.txBlock.add(...t)}publish({modules:t,dependencies:e}){return this.txBlock.publish({modules:t,dependencies:e})}upgrade(...t){return this.txBlock.upgrade(...t)}makeMoveVec(...t){return this.txBlock.makeMoveVec(...t)}transferObjects(t,e){return this.txBlock.transferObjects(t.map(i=>l(this.txBlock,i)),p(this.txBlock,e))}splitCoins(t,e){let i=this.txBlock.splitCoins(l(this.txBlock,t),d(this.txBlock,e));return e.map((n,s)=>i[s])}mergeCoins(t,e){let i=l(this.txBlock,t),n=e.map(s=>l(this.txBlock,s));return this.txBlock.mergeCoins(i,n)}moveCall(t,e=[],i=[]){let n=/(?<package>[a-zA-Z0-9]+)::(?<module>[a-zA-Z0-9_]+)::(?<function>[a-zA-Z0-9_]+)/;if(t.match(n)===null)throw new Error("Invalid target format. Expected `${string}::${string}::${string}`");let o=y(this.txBlock,e);return this.txBlock.moveCall({target:t,arguments:o,typeArguments:i})}transferSuiToMany(t,e){if(t.length!==e.length)throw new Error("transferSuiToMany: recipients.length !== amounts.length");let i=this.txBlock.splitCoins(this.txBlock.gas,d(this.txBlock,e));return t.map(s=>p(this.txBlock,s)).forEach((s,o)=>{this.txBlock.transferObjects([i[o]],s);}),this}transferSui(t,e){return this.transferSuiToMany([t],[e])}takeAmountFromCoins(t,e){let i=t.map(o=>l(this.txBlock,o)),n=i[0];t.length>1&&this.txBlock.mergeCoins(n,i.slice(1));let[s]=this.txBlock.splitCoins(n,d(this.txBlock,[e]));return [s,n]}splitSUIFromGas(t){return this.txBlock.splitCoins(this.txBlock.gas,d(this.txBlock,t))}splitMultiCoins(t,e){let i=t.map(o=>l(this.txBlock,o)),n=i[0];return t.length>1&&this.txBlock.mergeCoins(n,i.slice(1)),{splitedCoins:this.txBlock.splitCoins(n,d(this.txBlock,e)),mergedCoin:n}}transferCoinToMany(t,e,i,n){if(i.length!==n.length)throw new Error("transferSuiToMany: recipients.length !== amounts.length");let s=t.map(a=>l(this.txBlock,a)),{splitedCoins:o,mergedCoin:c}=this.splitMultiCoins(s,d(this.txBlock,n));return i.map(a=>p(this.txBlock,a)).forEach((a,m)=>{this.txBlock.transferObjects([o[m]],a);}),this.txBlock.transferObjects([c],p(this.txBlock,e)),this}transferCoin(t,e,i,n){return this.transferCoinToMany(t,e,[i],[n])}stakeSui(t,e){let[i]=this.txBlock.splitCoins(this.txBlock.gas,d(this.txBlock,[t]));return this.txBlock.moveCall({target:"0x3::sui_system::request_add_stake",arguments:y(this.txBlock,[this.txBlock.object(utils.SUI_SYSTEM_STATE_OBJECT_ID),i,p(this.txBlock,e)])})}};var A=class{constructor(t){this.objectId=t.objectId,this.version=t.version,this.digest=t.digest;}isFullObject(){return !!this.version&&!!this.digest}asCallArg(){return !this.version||!this.digest?this.objectId:{$kind:"Object",Object:{$kind:"ImmOrOwnedObject",ImmOrOwnedObject:{objectId:this.objectId,version:this.version,digest:this.digest}}}}updateFromTxResponse(t){let e=t.objectChanges;if(!e)throw new Error("Bad transaction response!");for(let i of e)if(i.type==="mutated"&&i.objectId===this.objectId){this.digest=i.digest,this.version=i.version;return}throw new Error("Could not find object in transaction response!")}};var x=class{constructor(t){this.objectId=t.objectId,this.initialSharedVersion=t.initialSharedVersion;}asCallArg(t=!1){return this.initialSharedVersion?{$kind:"Object",Object:{$kind:"SharedObject",SharedObject:{objectId:this.objectId,initialSharedVersion:this.initialSharedVersion,mutable:t}}}:this.objectId}};var P=r=>new Promise(t=>setTimeout(t,r)),V=(r,t)=>{let e=[];for(let i=0;i<r.length;i+=t)e.push(r.slice(i,i+t));return e};var b=class{constructor(t){this.clients=[];this.fullNodes=[];"fullnodeUrls"in t?(this.fullNodes=t.fullnodeUrls??[client.getFullnodeUrl("mainnet")],this.clients=this.fullNodes.map(e=>new client.SuiClient({url:e}))):"suiClients"in t&&t.suiClients?this.clients=t.suiClients:this.clients=[new client.SuiClient({url:client.getFullnodeUrl("mainnet")})],this.currentClient=this.clients[0];}switchToNextClient(){let t=this.clients.indexOf(this.currentClient);this.currentClient=this.clients[(t+1)%this.clients.length];}switchFullNodes(t){if(t.length===0)throw new Error("fullNodes cannot be empty");this.fullNodes=t,this.clients=t.map(e=>new client.SuiClient({url:e})),this.currentClient=this.clients[0];}get currentFullNode(){if(this.fullNodes.length===0)throw new Error("No full nodes available");let t=this.clients.indexOf(this.currentClient);if(t===-1)throw new Error("Current client not found");return this.fullNodes[t]}async sendTx(t,e){let i={showEvents:!0,showEffects:!0,showRawEffects:!0,showObjectChanges:!0,showBalanceChanges:!0};for(let n in this.clients)try{return await this.clients[n].executeTransactionBlock({transactionBlock:t,signature:e,options:i})}catch(s){console.warn(`Failed to send transaction with fullnode ${this.fullNodes[n]}: ${s}`),await P(2e3);}throw new Error("Failed to send transaction with all fullnodes")}async dryRunTx(t){for(let e in this.clients)try{return await this.clients[e].dryRunTransactionBlock({transactionBlock:t})}catch(i){console.warn(`Failed to dry run transaction with fullnode ${this.fullNodes[e]}: ${i}`),await P(2e3);}throw new Error("Failed to dry run transaction with all fullnodes")}async getObjects(t,e){let i=e??{showContent:!0,showDisplay:!0,showType:!0,showOwner:!0},n=V(t,Math.max(e?.batchSize??50,50)),s=[],o=null;for(let c of n){for(let h in this.clients)try{let m=(await this.clients[h].multiGetObjects({ids:c,options:i})).map(g=>g.data).filter(g=>g!=null);s.push(...m),o=null;break}catch(a){o=a instanceof Error?a:new Error(String(a)),await P(e?.switchClientDelay??2e3),console.warn(`Failed to get objects with fullnode ${this.fullNodes[h]}: ${a}`);}if(o)throw new Error(`Failed to get objects with all fullnodes: ${o}`)}return s}async getObject(t,e){return (await this.getObjects([t],e))[0]}async updateObjects(t){let e=t.map(n=>n.objectId),i=await this.getObjects(e);for(let n of i){let s=t.find(o=>o.objectId===n?.objectId);s instanceof x?n.owner&&typeof n.owner=="object"&&"Shared"in n.owner?s.initialSharedVersion=n.owner.Shared.initial_shared_version:s.initialSharedVersion=void 0:s instanceof A&&(s.version=n?.version,s.digest=n?.digest);}}async selectCoins(t,e,i="0x2::SUI::SUI"){let n=[],s=0,o=!0,c=null;for(;o&&s<e;){let h=await this.currentClient.getCoins({owner:t,coinType:i,cursor:c});h.data.sort((a,m)=>parseInt(m.balance)-parseInt(a.balance));for(let a of h.data)if(n.push({objectId:a.coinObjectId,digest:a.digest,version:a.version,balance:a.balance}),s=s+parseInt(a.balance),s>=e)break;c=h.nextCursor,o=h.hasNextPage;}if(!n.length)throw new Error("No valid coins found for the transaction.");return n}};var k=class{constructor(t){let{mnemonics:e,secretKey:i,networkType:n}=t;this.accountManager=new f({mnemonics:e,secretKey:i});let s;"fullnodeUrls"in t?s={fullnodeUrls:t.fullnodeUrls}:"suiClients"in t?s={suiClients:t.suiClients}:s={fullnodeUrls:[client.getFullnodeUrl(n??"mainnet")]},this.suiInteractor=new b(s);}createTxBlock(){let t=new u;return t.setSender(this.accountManager.currentAddress),t}getKeypair(t){return this.accountManager.getKeyPair(t)}switchAccount(t){this.accountManager.switchAccount(t);}getAddress(t){return this.accountManager.getAddress(t)}get currentAddress(){return this.accountManager.currentAddress}async getBalance(t,e){let i=this.accountManager.getAddress(e);return this.suiInteractor.currentClient.getBalance({owner:i,coinType:t})}get client(){return this.suiInteractor.currentClient}async getObjects(t,e){return this.suiInteractor.getObjects(t,e)}async updateObjects(t){return this.suiInteractor.updateObjects(t)}async signTxn(t,e){t instanceof u&&t.setSender(this.getAddress(e));let i=t instanceof u?t.txBlock:t,n=i instanceof transactions.Transaction?await i.build({client:this.client}):i;return await this.getKeypair(e).signTransaction(n)}async signAndSendTxn(t,e){let{bytes:i,signature:n}=await this.signTxn(t,e);return this.suiInteractor.sendTx(i,n)}async dryRunTxn(t,e){t instanceof u&&t.setSender(this.getAddress(e));let i=t instanceof u?t.txBlock:t,n=i instanceof transactions.Transaction?await i.build({client:this.client}):i;return this.suiInteractor.dryRunTx(n)}async transferSui(t,e,i=!0,n){let s=new u;return s.transferSui(t,e),i?await this.signAndSendTxn(s,n):s}async transferSuiToMany(t,e,i=!0,n){let s=new u;return s.transferSuiToMany(t,e),i?await this.signAndSendTxn(s,n):s}async transferCoinToMany(t,e,i,n=!0,s){let o=new u,c=this.accountManager.getAddress(s),h=e.reduce((m,g)=>m+g,0),a=await this.suiInteractor.selectCoins(c,h,i);return o.transferCoinToMany(a.map(m=>m.objectId),c,t,e),n?await this.signAndSendTxn(o,s):o}async transferCoin(t,e,i,n=!0,s){return this.transferCoinToMany([t],[e],i,n,s)}async transferObjects(t,e,i=!0,n){let s=new u;return s.transferObjects(t,e),i?await this.signAndSendTxn(s,n):s}async moveCall(t){let{target:e,arguments:i=[],typeArguments:n=[],derivePathParams:s}=t,o=new u;return o.moveCall(e,i,n),this.signAndSendTxn(o,s)}async selectCoinsWithAmount(t,e,i){return i=i||this.accountManager.currentAddress,await this.suiInteractor.selectCoins(i,t,e)}async stakeSui(t,e,i=!0,n){let s=new u;return s.stakeSui(t,e),i?await this.signAndSendTxn(s,n):s}async inspectTxn(t,e){let i=t instanceof u?t.txBlock:t;return this.suiInteractor.currentClient.devInspectTransactionBlock({transactionBlock:i,sender:this.getAddress(e)})}};function N(r){let t=utils.fromB64(r);if(t.length!==32&&t.length!==33)throw "invalid pubkey length";return t=t.length===33?t.slice(1):t,new ed25519.Ed25519PublicKey(t)}var j=class r{constructor(t,e){this.pksWeightPairs=t,this.threshold=e,this.multiSigPublicKey=multisig.MultiSigPublicKey.fromPublicKeys({threshold:this.threshold,publicKeys:this.pksWeightPairs});}static fromRawEd25519PublicKeys(t,e,i){let n=t.map((s,o)=>({publicKey:N(s),weight:e[o]}));return new r(n,i)}multiSigAddress(){return this.multiSigPublicKey.toSuiAddress()}combinePartialSigs(t){return this.multiSigPublicKey.combinePartialSignatures(t)}};
14
14
 
15
- exports.MultiSigClient = x;
16
- exports.SuiAccountManager = S;
17
- exports.SuiInteractor = g;
18
- exports.SuiKit = O;
19
- exports.SuiTxBlock = c;
15
+ exports.MultiSigClient = j;
16
+ exports.SuiAccountManager = f;
17
+ exports.SuiInteractor = b;
18
+ exports.SuiKit = k;
19
+ exports.SuiTxBlock = u;
20
20
  Object.keys(utils).forEach(function (k) {
21
21
  if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
22
22
  enumerable: true,
package/dist/index.mjs CHANGED
@@ -10,6 +10,6 @@ import { SUI_PRIVATE_KEY_PREFIX, decodeSuiPrivateKey } from '@mysten/sui/cryptog
10
10
  import { SerializedBcs, isSerializedBcs, bcs } from '@mysten/bcs';
11
11
  import { MultiSigPublicKey } from '@mysten/sui/multisig';
12
12
 
13
- var F=(r={})=>{let{accountIndex:t=0,isExternal:e=!1,addressIndex:i=0}=r;return `m/44'/784'/${t}'/${e?1:0}'/${i}'`},b=(r,t={})=>{let e=F(t);return Ed25519Keypair.deriveKeypair(r,e)};var G=r=>/^0x[0-9a-fA-F]+$|^[0-9a-fA-F]+$/.test(r),z=r=>/^[a-zA-Z0-9+/]+={0,2}$/g.test(r),W=r=>{if(!r)throw new Error("cannot parse empty string to Uint8Array");let t=r.replace("0x","").match(/.{1,2}/g)?.map(e=>parseInt(e,16));if(!t||t.length===0)throw new Error(`Unable to parse HEX: ${r}`);return Uint8Array.from(t)},k=r=>{if(G(r))return W(r);if(z(r))return fromB64(r);throw new Error("The string is not a valid hex or base64 string.")},j=32,Z=64,T=r=>{if(r.length===Z)r=r.slice(0,j);else {if(r.length===j+1&&r[0]===0)return r.slice(1);if(r.length===j)return r}throw new Error("invalid secret key")};var w=(r=24)=>generateMnemonic(wordlist,r===12?128:256);var S=class{constructor({mnemonics:t,secretKey:e}={}){this.mnemonics=t||"",this.secretKey=e||"",!this.mnemonics&&!this.secretKey&&(this.mnemonics=w(24)),this.currentKeyPair=this.secretKey?this.parseSecretKey(this.secretKey):b(this.mnemonics),this.currentAddress=this.currentKeyPair.getPublicKey().toSuiAddress();}parseSecretKey(t){if(t.startsWith(SUI_PRIVATE_KEY_PREFIX)){let{secretKey:e}=decodeSuiPrivateKey(t);return Ed25519Keypair.fromSecretKey(T(e))}return Ed25519Keypair.fromSecretKey(T(k(t)))}getKeyPair(t){return !t||!this.mnemonics?this.currentKeyPair:b(this.mnemonics,t)}getAddress(t){return !t||!this.mnemonics?this.currentAddress:b(this.mnemonics,t).getPublicKey().toSuiAddress()}switchAccount(t){this.mnemonics&&(this.currentKeyPair=b(this.mnemonics,t),this.currentAddress=this.currentKeyPair.getPublicKey().toSuiAddress());}};var it=r=>typeof r=="string"&&isValidSuiObjectId(r)?"object":typeof r=="number"||typeof r=="bigint"?"u64":typeof r=="boolean"?"bool":void 0;function R(r){return typeof r=="number"||typeof r=="bigint"||typeof r=="string"&&!isValidSuiAddress(r)&&!isNaN(Number(r))}function nt(r){return typeof r=="object"&&"vecType"in r&&"value"in r?!0:!!Array.isArray(r)}function st(r){return typeof r=="object"&&"digest"in r&&"version"in r&&"objectId"in r}function ot(r){return typeof r=="object"&&"objectId"in r&&"initialSharedVersion"in r&&"mutable"in r}function I(r,t,e){if(t.length===0)throw new Error("Transaction builder error: Empty array is not allowed");let i=it(t[0]),n=/^vector<(.+)>$/,s=/^([^:]+)::([^:]+)::([^<]+)(<(.+)>)?/;if(e=e||i,e==="object"){let o=t.map(a=>typeof a=="string"&&isValidSuiObjectId(a)?r.object(normalizeSuiObjectId(a)):l(r,a));return r.makeMoveVec({elements:o})}else if(typeof e=="string"&&!n.test(e)&&!s.test(e)){let o=getPureBcsSchema(e);return r.pure(bcs.vector(o).serialize(t))}else {let o=t.map(a=>l(r,a));return r.makeMoveVec({elements:o,type:e})}}function f(r,t){return t.map(e=>e instanceof SerializedBcs||isSerializedBcs(e)?r.pure(e):nt(e)?"vecType"in e?I(r,e.value,e.vecType):I(r,e):R(e)?m(r,[e])[0]:l(r,e))}function p(r,t){return typeof t=="string"&&isValidSuiAddress(t)?r.pure.address(normalizeSuiAddress(t)):f(r,[t])[0]}function l(r,t){if(typeof t=="string")return r.object(t);if(st(t))return r.objectRef(t);if(ot(t))return r.sharedObjectRef(t);if("Object"in t){if("ImmOrOwnedObject"in t.Object)return r.object(Inputs.ObjectRef(t.Object.ImmOrOwnedObject));if("SharedObject"in t.Object)return r.object(Inputs.SharedObjectRef(t.Object.SharedObject));throw new Error("Invalid argument type")}if(typeof t=="function"||"GasCoin"in t||"Input"in t||"Result"in t||"NestedResult"in t)return t;throw new Error("Invalid argument type")}function m(r,t){return t.map(e=>R(e)?r.pure.u64(e):f(r,[e])[0])}var c=class{constructor(t){this.txBlock=t?Transaction.from(t):new Transaction;}get gas(){return this.txBlock.gas}get blockData(){return this.txBlock.blockData}get getData(){return this.txBlock.getData()}address(t){return this.txBlock.pure.address(t)}get pure(){return this.txBlock.pure}object(t){return this.txBlock.object(t)}objectRef(t){return this.txBlock.objectRef(t)}sharedObjectRef(t){return this.txBlock.sharedObjectRef(t)}setSender(t){return this.txBlock.setSender(t)}setSenderIfNotSet(t){return this.txBlock.setSenderIfNotSet(t)}setExpiration(t){return this.txBlock.setExpiration(t)}setGasPrice(t){return this.txBlock.setGasPrice(t)}setGasBudget(t){return this.txBlock.setGasBudget(t)}setGasOwner(t){return this.txBlock.setGasOwner(t)}setGasPayment(t){return this.txBlock.setGasPayment(t)}serialize(){return this.txBlock.serialize()}toJSON(){return this.txBlock.toJSON()}sign(t){return this.txBlock.sign(t)}build(t={}){return this.txBlock.build(t)}getDigest(t={}){return this.txBlock.getDigest(t)}add(...t){return this.txBlock.add(...t)}publish({modules:t,dependencies:e}){return this.txBlock.publish({modules:t,dependencies:e})}upgrade(...t){return this.txBlock.upgrade(...t)}makeMoveVec(...t){return this.txBlock.makeMoveVec(...t)}transferObjects(t,e){return this.txBlock.transferObjects(t.map(i=>l(this.txBlock,i)),p(this.txBlock,e))}splitCoins(t,e){let i=this.txBlock.splitCoins(l(this.txBlock,t),m(this.txBlock,e));return e.map((n,s)=>i[s])}mergeCoins(t,e){let i=l(this.txBlock,t),n=e.map(s=>l(this.txBlock,s));return this.txBlock.mergeCoins(i,n)}moveCall(t,e=[],i=[]){let n=/(?<package>[a-zA-Z0-9]+)::(?<module>[a-zA-Z0-9_]+)::(?<function>[a-zA-Z0-9_]+)/;if(t.match(n)===null)throw new Error("Invalid target format. Expected `${string}::${string}::${string}`");let o=f(this.txBlock,e);return this.txBlock.moveCall({target:t,arguments:o,typeArguments:i})}transferSuiToMany(t,e){if(t.length!==e.length)throw new Error("transferSuiToMany: recipients.length !== amounts.length");let i=this.txBlock.splitCoins(this.txBlock.gas,m(this.txBlock,e));return t.map(s=>p(this.txBlock,s)).forEach((s,o)=>{this.txBlock.transferObjects([i[o]],s);}),this}transferSui(t,e){return this.transferSuiToMany([t],[e])}takeAmountFromCoins(t,e){let i=t.map(o=>l(this.txBlock,o)),n=i[0];t.length>1&&this.txBlock.mergeCoins(n,i.slice(1));let[s]=this.txBlock.splitCoins(n,m(this.txBlock,[e]));return [s,n]}splitSUIFromGas(t){return this.txBlock.splitCoins(this.txBlock.gas,m(this.txBlock,t))}splitMultiCoins(t,e){let i=t.map(o=>l(this.txBlock,o)),n=i[0];return t.length>1&&this.txBlock.mergeCoins(n,i.slice(1)),{splitedCoins:this.txBlock.splitCoins(n,m(this.txBlock,e)),mergedCoin:n}}transferCoinToMany(t,e,i,n){if(i.length!==n.length)throw new Error("transferSuiToMany: recipients.length !== amounts.length");let s=t.map(u=>l(this.txBlock,u)),{splitedCoins:o,mergedCoin:a}=this.splitMultiCoins(s,m(this.txBlock,n));return i.map(u=>p(this.txBlock,u)).forEach((u,d)=>{this.txBlock.transferObjects([o[d]],u);}),this.txBlock.transferObjects([a],p(this.txBlock,e)),this}transferCoin(t,e,i,n){return this.transferCoinToMany(t,e,[i],[n])}stakeSui(t,e){let[i]=this.txBlock.splitCoins(this.txBlock.gas,m(this.txBlock,[t]));return this.txBlock.moveCall({target:"0x3::sui_system::request_add_stake",arguments:f(this.txBlock,[this.txBlock.object(SUI_SYSTEM_STATE_OBJECT_ID),i,p(this.txBlock,e)])})}};var y=class{constructor(t){this.objectId=t.objectId,this.version=t.version,this.digest=t.digest;}isFullObject(){return !!this.version&&!!this.digest}asCallArg(){return !this.version||!this.digest?this.objectId:{$kind:"Object",Object:{$kind:"ImmOrOwnedObject",ImmOrOwnedObject:{objectId:this.objectId,version:this.version,digest:this.digest}}}}updateFromTxResponse(t){let e=t.objectChanges;if(!e)throw new Error("Bad transaction response!");for(let i of e)if(i.type==="mutated"&&i.objectId===this.objectId){this.digest=i.digest,this.version=i.version;return}throw new Error("Could not find object in transaction response!")}};var A=class{constructor(t){this.objectId=t.objectId,this.initialSharedVersion=t.initialSharedVersion;}asCallArg(t=!1){return this.initialSharedVersion?{$kind:"Object",Object:{$kind:"SharedObject",SharedObject:{objectId:this.objectId,initialSharedVersion:this.initialSharedVersion,mutable:t}}}:this.objectId}};var P=r=>new Promise(t=>setTimeout(t,r));var g=class{constructor(t){this.clients=[];this.fullNodes=[];"fullnodeUrls"in t?(this.fullNodes=t.fullnodeUrls??[getFullnodeUrl("mainnet")],this.clients=this.fullNodes.map(e=>new SuiClient({url:e}))):"suiClients"in t&&t.suiClients?this.clients=t.suiClients:this.clients=[new SuiClient({url:getFullnodeUrl("mainnet")})],this.currentClient=this.clients[0];}switchToNextClient(){let t=this.clients.indexOf(this.currentClient);this.currentClient=this.clients[(t+1)%this.clients.length];}async sendTx(t,e){let i={showEvents:!0,showEffects:!0,showRawEffects:!0,showObjectChanges:!0,showBalanceChanges:!0};for(let n in this.clients)try{return await this.clients[n].executeTransactionBlock({transactionBlock:t,signature:e,options:i})}catch(s){console.warn(`Failed to send transaction with fullnode ${this.fullNodes[n]}: ${s}`),await P(2e3);}throw new Error("Failed to send transaction with all fullnodes")}async dryRunTx(t){for(let e in this.clients)try{return await this.clients[e].dryRunTransactionBlock({transactionBlock:t})}catch(i){console.warn(`Failed to dry run transaction with fullnode ${this.fullNodes[e]}: ${i}`),await P(2e3);}throw new Error("Failed to dry run transaction with all fullnodes")}async getObjects(t,e){let i=e??{showContent:!0,showDisplay:!0,showType:!0,showOwner:!0};for(let n in this.clients)try{return (await this.clients[n].multiGetObjects({ids:t,options:i})).map(a=>a.data).filter(a=>a!=null)}catch(s){await P(2e3),console.warn(`Failed to get objects with fullnode ${this.fullNodes[n]}: ${s}`);}throw new Error("Failed to get objects with all fullnodes")}async getObject(t,e){return (await this.getObjects([t],e))[0]}async updateObjects(t){let e=t.map(n=>n.objectId),i=await this.getObjects(e);for(let n of i){let s=t.find(o=>o.objectId===n?.objectId);s instanceof A?n.owner&&typeof n.owner=="object"&&"Shared"in n.owner?s.initialSharedVersion=n.owner.Shared.initial_shared_version:s.initialSharedVersion=void 0:s instanceof y&&(s.version=n?.version,s.digest=n?.digest);}}async selectCoins(t,e,i="0x2::SUI::SUI"){let n=[],s=0,o=!0,a=null;for(;o&&s<e;){let h=await this.currentClient.getCoins({owner:t,coinType:i,cursor:a});h.data.sort((u,d)=>parseInt(d.balance)-parseInt(u.balance));for(let u of h.data)if(n.push({objectId:u.coinObjectId,digest:u.digest,version:u.version,balance:u.balance}),s=s+parseInt(u.balance),s>=e)break;a=h.nextCursor,o=h.hasNextPage;}if(!n.length)throw new Error("No valid coins found for the transaction.");return n}};var O=class{constructor(t){let{mnemonics:e,secretKey:i,networkType:n}=t;this.accountManager=new S({mnemonics:e,secretKey:i});let s;"fullnodeUrls"in t?s={fullnodeUrls:t.fullnodeUrls}:"suiClients"in t?s={suiClients:t.suiClients}:s={fullnodeUrls:[getFullnodeUrl(n??"mainnet")]},this.suiInteractor=new g(s);}createTxBlock(){let t=new c;return t.setSender(this.accountManager.currentAddress),t}getKeypair(t){return this.accountManager.getKeyPair(t)}switchAccount(t){this.accountManager.switchAccount(t);}getAddress(t){return this.accountManager.getAddress(t)}currentAddress(){return this.accountManager.currentAddress}async getBalance(t,e){let i=this.accountManager.getAddress(e);return this.suiInteractor.currentClient.getBalance({owner:i,coinType:t})}client(){return this.suiInteractor.currentClient}async getObjects(t,e){return this.suiInteractor.getObjects(t,e)}async updateObjects(t){return this.suiInteractor.updateObjects(t)}async signTxn(t,e){t instanceof c&&t.setSender(this.getAddress(e));let i=t instanceof c?t.txBlock:t,n=i instanceof Transaction?await i.build({client:this.client()}):i;return await this.getKeypair(e).signTransaction(n)}async signAndSendTxn(t,e){let{bytes:i,signature:n}=await this.signTxn(t,e);return this.suiInteractor.sendTx(i,n)}async dryRunTxn(t,e){t instanceof c&&t.setSender(this.getAddress(e));let i=t instanceof c?t.txBlock:t,n=i instanceof Transaction?await i.build({client:this.client()}):i;return this.suiInteractor.dryRunTx(n)}async transferSui(t,e,i=!0,n){let s=new c;return s.transferSui(t,e),i?await this.signAndSendTxn(s,n):s}async transferSuiToMany(t,e,i=!0,n){let s=new c;return s.transferSuiToMany(t,e),i?await this.signAndSendTxn(s,n):s}async transferCoinToMany(t,e,i,n=!0,s){let o=new c,a=this.accountManager.getAddress(s),h=e.reduce((d,$)=>d+$,0),u=await this.suiInteractor.selectCoins(a,h,i);return o.transferCoinToMany(u.map(d=>d.objectId),a,t,e),n?await this.signAndSendTxn(o,s):o}async transferCoin(t,e,i,n=!0,s){return this.transferCoinToMany([t],[e],i,n,s)}async transferObjects(t,e,i=!0,n){let s=new c;return s.transferObjects(t,e),i?await this.signAndSendTxn(s,n):s}async moveCall(t){let{target:e,arguments:i=[],typeArguments:n=[],derivePathParams:s}=t,o=new c;return o.moveCall(e,i,n),this.signAndSendTxn(o,s)}async selectCoinsWithAmount(t,e,i){return i=i||this.accountManager.currentAddress,await this.suiInteractor.selectCoins(i,t,e)}async stakeSui(t,e,i=!0,n){let s=new c;return s.stakeSui(t,e),i?await this.signAndSendTxn(s,n):s}async inspectTxn(t,e){let i=t instanceof c?t.txBlock:t;return this.suiInteractor.currentClient.devInspectTransactionBlock({transactionBlock:i,sender:this.getAddress(e)})}};function U(r){let t=fromB64(r);if(t.length!==32&&t.length!==33)throw "invalid pubkey length";return t=t.length===33?t.slice(1):t,new Ed25519PublicKey(t)}var x=class r{constructor(t,e){this.pksWeightPairs=t,this.threshold=e,this.multiSigPublicKey=MultiSigPublicKey.fromPublicKeys({threshold:this.threshold,publicKeys:this.pksWeightPairs});}static fromRawEd25519PublicKeys(t,e,i){let n=t.map((s,o)=>({publicKey:U(s),weight:e[o]}));return new r(n,i)}multiSigAddress(){return this.multiSigPublicKey.toSuiAddress()}combinePartialSigs(t){return this.multiSigPublicKey.combinePartialSignatures(t)}};
13
+ var F=(r={})=>{let{accountIndex:t=0,isExternal:e=!1,addressIndex:i=0}=r;return `m/44'/784'/${t}'/${e?1:0}'/${i}'`},S=(r,t={})=>{let e=F(t);return Ed25519Keypair.deriveKeypair(r,e)};var G=r=>/^0x[0-9a-fA-F]+$|^[0-9a-fA-F]+$/.test(r),W=r=>/^[a-zA-Z0-9+/]+={0,2}$/g.test(r),Z=r=>{if(!r)throw new Error("cannot parse empty string to Uint8Array");let t=r.replace("0x","").match(/.{1,2}/g)?.map(e=>parseInt(e,16));if(!t||t.length===0)throw new Error(`Unable to parse HEX: ${r}`);return Uint8Array.from(t)},B=r=>{if(G(r))return Z(r);if(W(r))return fromB64(r);throw new Error("The string is not a valid hex or base64 string.")},T=32,X=64,O=r=>{if(r.length===X)r=r.slice(0,T);else {if(r.length===T+1&&r[0]===0)return r.slice(1);if(r.length===T)return r}throw new Error("invalid secret key")};var v=(r=24)=>generateMnemonic(wordlist,r===12?128:256);var f=class{constructor({mnemonics:t,secretKey:e}={}){this.mnemonics=t||"",this.secretKey=e||"",!this.mnemonics&&!this.secretKey&&(this.mnemonics=v(24)),this.currentKeyPair=this.secretKey?this.parseSecretKey(this.secretKey):S(this.mnemonics),this.currentAddress=this.currentKeyPair.getPublicKey().toSuiAddress();}parseSecretKey(t){if(t.startsWith(SUI_PRIVATE_KEY_PREFIX)){let{secretKey:e}=decodeSuiPrivateKey(t);return Ed25519Keypair.fromSecretKey(O(e))}return Ed25519Keypair.fromSecretKey(O(B(t)))}getKeyPair(t){return !t||!this.mnemonics?this.currentKeyPair:S(this.mnemonics,t)}getAddress(t){return !t||!this.mnemonics?this.currentAddress:S(this.mnemonics,t).getPublicKey().toSuiAddress()}switchAccount(t){this.mnemonics&&(this.currentKeyPair=S(this.mnemonics,t),this.currentAddress=this.currentKeyPair.getPublicKey().toSuiAddress());}};var nt=r=>typeof r=="string"&&isValidSuiObjectId(r)?"object":typeof r=="number"||typeof r=="bigint"?"u64":typeof r=="boolean"?"bool":void 0;function E(r){return typeof r=="number"||typeof r=="bigint"||typeof r=="string"&&!isValidSuiAddress(r)&&!isNaN(Number(r))}function st(r){return typeof r=="object"&&"vecType"in r&&"value"in r?!0:!!Array.isArray(r)}function ot(r){return typeof r=="object"&&"digest"in r&&"version"in r&&"objectId"in r}function at(r){return typeof r=="object"&&"objectId"in r&&"initialSharedVersion"in r&&"mutable"in r}function K(r,t,e){if(t.length===0)throw new Error("Transaction builder error: Empty array is not allowed");let i=nt(t[0]),n=/^vector<(.+)>$/,s=/^([^:]+)::([^:]+)::([^<]+)(<(.+)>)?/;if(e=e||i,e==="object"){let o=t.map(c=>typeof c=="string"&&isValidSuiObjectId(c)?r.object(normalizeSuiObjectId(c)):l(r,c));return r.makeMoveVec({elements:o})}else if(typeof e=="string"&&!n.test(e)&&!s.test(e)){let o=getPureBcsSchema(e);return r.pure(bcs.vector(o).serialize(t))}else {let o=t.map(c=>l(r,c));return r.makeMoveVec({elements:o,type:e})}}function y(r,t){return t.map(e=>e instanceof SerializedBcs||isSerializedBcs(e)?r.pure(e):st(e)?"vecType"in e?K(r,e.value,e.vecType):K(r,e):E(e)?d(r,[e])[0]:l(r,e))}function p(r,t){return typeof t=="string"&&isValidSuiAddress(t)?r.pure.address(normalizeSuiAddress(t)):y(r,[t])[0]}function l(r,t){if(typeof t=="string")return r.object(t);if(ot(t))return r.objectRef(t);if(at(t))return r.sharedObjectRef(t);if("Object"in t){if("ImmOrOwnedObject"in t.Object)return r.object(Inputs.ObjectRef(t.Object.ImmOrOwnedObject));if("SharedObject"in t.Object)return r.object(Inputs.SharedObjectRef(t.Object.SharedObject));throw new Error("Invalid argument type")}if(typeof t=="function"||"GasCoin"in t||"Input"in t||"Result"in t||"NestedResult"in t)return t;throw new Error("Invalid argument type")}function d(r,t){return t.map(e=>E(e)?r.pure.u64(e):y(r,[e])[0])}var u=class{constructor(t){this.txBlock=t?Transaction.from(t):new Transaction;}get gas(){return this.txBlock.gas}get blockData(){return this.txBlock.blockData}get getData(){return this.txBlock.getData()}address(t){return this.txBlock.pure.address(t)}get pure(){return this.txBlock.pure}object(t){return this.txBlock.object(t)}objectRef(t){return this.txBlock.objectRef(t)}sharedObjectRef(t){return this.txBlock.sharedObjectRef(t)}setSender(t){return this.txBlock.setSender(t)}setSenderIfNotSet(t){return this.txBlock.setSenderIfNotSet(t)}setExpiration(t){return this.txBlock.setExpiration(t)}setGasPrice(t){return this.txBlock.setGasPrice(t)}setGasBudget(t){return this.txBlock.setGasBudget(t)}setGasOwner(t){return this.txBlock.setGasOwner(t)}setGasPayment(t){return this.txBlock.setGasPayment(t)}serialize(){return this.txBlock.serialize()}toJSON(){return this.txBlock.toJSON()}sign(t){return this.txBlock.sign(t)}build(t={}){return this.txBlock.build(t)}getDigest(t={}){return this.txBlock.getDigest(t)}add(...t){return this.txBlock.add(...t)}publish({modules:t,dependencies:e}){return this.txBlock.publish({modules:t,dependencies:e})}upgrade(...t){return this.txBlock.upgrade(...t)}makeMoveVec(...t){return this.txBlock.makeMoveVec(...t)}transferObjects(t,e){return this.txBlock.transferObjects(t.map(i=>l(this.txBlock,i)),p(this.txBlock,e))}splitCoins(t,e){let i=this.txBlock.splitCoins(l(this.txBlock,t),d(this.txBlock,e));return e.map((n,s)=>i[s])}mergeCoins(t,e){let i=l(this.txBlock,t),n=e.map(s=>l(this.txBlock,s));return this.txBlock.mergeCoins(i,n)}moveCall(t,e=[],i=[]){let n=/(?<package>[a-zA-Z0-9]+)::(?<module>[a-zA-Z0-9_]+)::(?<function>[a-zA-Z0-9_]+)/;if(t.match(n)===null)throw new Error("Invalid target format. Expected `${string}::${string}::${string}`");let o=y(this.txBlock,e);return this.txBlock.moveCall({target:t,arguments:o,typeArguments:i})}transferSuiToMany(t,e){if(t.length!==e.length)throw new Error("transferSuiToMany: recipients.length !== amounts.length");let i=this.txBlock.splitCoins(this.txBlock.gas,d(this.txBlock,e));return t.map(s=>p(this.txBlock,s)).forEach((s,o)=>{this.txBlock.transferObjects([i[o]],s);}),this}transferSui(t,e){return this.transferSuiToMany([t],[e])}takeAmountFromCoins(t,e){let i=t.map(o=>l(this.txBlock,o)),n=i[0];t.length>1&&this.txBlock.mergeCoins(n,i.slice(1));let[s]=this.txBlock.splitCoins(n,d(this.txBlock,[e]));return [s,n]}splitSUIFromGas(t){return this.txBlock.splitCoins(this.txBlock.gas,d(this.txBlock,t))}splitMultiCoins(t,e){let i=t.map(o=>l(this.txBlock,o)),n=i[0];return t.length>1&&this.txBlock.mergeCoins(n,i.slice(1)),{splitedCoins:this.txBlock.splitCoins(n,d(this.txBlock,e)),mergedCoin:n}}transferCoinToMany(t,e,i,n){if(i.length!==n.length)throw new Error("transferSuiToMany: recipients.length !== amounts.length");let s=t.map(a=>l(this.txBlock,a)),{splitedCoins:o,mergedCoin:c}=this.splitMultiCoins(s,d(this.txBlock,n));return i.map(a=>p(this.txBlock,a)).forEach((a,m)=>{this.txBlock.transferObjects([o[m]],a);}),this.txBlock.transferObjects([c],p(this.txBlock,e)),this}transferCoin(t,e,i,n){return this.transferCoinToMany(t,e,[i],[n])}stakeSui(t,e){let[i]=this.txBlock.splitCoins(this.txBlock.gas,d(this.txBlock,[t]));return this.txBlock.moveCall({target:"0x3::sui_system::request_add_stake",arguments:y(this.txBlock,[this.txBlock.object(SUI_SYSTEM_STATE_OBJECT_ID),i,p(this.txBlock,e)])})}};var A=class{constructor(t){this.objectId=t.objectId,this.version=t.version,this.digest=t.digest;}isFullObject(){return !!this.version&&!!this.digest}asCallArg(){return !this.version||!this.digest?this.objectId:{$kind:"Object",Object:{$kind:"ImmOrOwnedObject",ImmOrOwnedObject:{objectId:this.objectId,version:this.version,digest:this.digest}}}}updateFromTxResponse(t){let e=t.objectChanges;if(!e)throw new Error("Bad transaction response!");for(let i of e)if(i.type==="mutated"&&i.objectId===this.objectId){this.digest=i.digest,this.version=i.version;return}throw new Error("Could not find object in transaction response!")}};var x=class{constructor(t){this.objectId=t.objectId,this.initialSharedVersion=t.initialSharedVersion;}asCallArg(t=!1){return this.initialSharedVersion?{$kind:"Object",Object:{$kind:"SharedObject",SharedObject:{objectId:this.objectId,initialSharedVersion:this.initialSharedVersion,mutable:t}}}:this.objectId}};var P=r=>new Promise(t=>setTimeout(t,r)),V=(r,t)=>{let e=[];for(let i=0;i<r.length;i+=t)e.push(r.slice(i,i+t));return e};var b=class{constructor(t){this.clients=[];this.fullNodes=[];"fullnodeUrls"in t?(this.fullNodes=t.fullnodeUrls??[getFullnodeUrl("mainnet")],this.clients=this.fullNodes.map(e=>new SuiClient({url:e}))):"suiClients"in t&&t.suiClients?this.clients=t.suiClients:this.clients=[new SuiClient({url:getFullnodeUrl("mainnet")})],this.currentClient=this.clients[0];}switchToNextClient(){let t=this.clients.indexOf(this.currentClient);this.currentClient=this.clients[(t+1)%this.clients.length];}switchFullNodes(t){if(t.length===0)throw new Error("fullNodes cannot be empty");this.fullNodes=t,this.clients=t.map(e=>new SuiClient({url:e})),this.currentClient=this.clients[0];}get currentFullNode(){if(this.fullNodes.length===0)throw new Error("No full nodes available");let t=this.clients.indexOf(this.currentClient);if(t===-1)throw new Error("Current client not found");return this.fullNodes[t]}async sendTx(t,e){let i={showEvents:!0,showEffects:!0,showRawEffects:!0,showObjectChanges:!0,showBalanceChanges:!0};for(let n in this.clients)try{return await this.clients[n].executeTransactionBlock({transactionBlock:t,signature:e,options:i})}catch(s){console.warn(`Failed to send transaction with fullnode ${this.fullNodes[n]}: ${s}`),await P(2e3);}throw new Error("Failed to send transaction with all fullnodes")}async dryRunTx(t){for(let e in this.clients)try{return await this.clients[e].dryRunTransactionBlock({transactionBlock:t})}catch(i){console.warn(`Failed to dry run transaction with fullnode ${this.fullNodes[e]}: ${i}`),await P(2e3);}throw new Error("Failed to dry run transaction with all fullnodes")}async getObjects(t,e){let i=e??{showContent:!0,showDisplay:!0,showType:!0,showOwner:!0},n=V(t,Math.max(e?.batchSize??50,50)),s=[],o=null;for(let c of n){for(let h in this.clients)try{let m=(await this.clients[h].multiGetObjects({ids:c,options:i})).map(g=>g.data).filter(g=>g!=null);s.push(...m),o=null;break}catch(a){o=a instanceof Error?a:new Error(String(a)),await P(e?.switchClientDelay??2e3),console.warn(`Failed to get objects with fullnode ${this.fullNodes[h]}: ${a}`);}if(o)throw new Error(`Failed to get objects with all fullnodes: ${o}`)}return s}async getObject(t,e){return (await this.getObjects([t],e))[0]}async updateObjects(t){let e=t.map(n=>n.objectId),i=await this.getObjects(e);for(let n of i){let s=t.find(o=>o.objectId===n?.objectId);s instanceof x?n.owner&&typeof n.owner=="object"&&"Shared"in n.owner?s.initialSharedVersion=n.owner.Shared.initial_shared_version:s.initialSharedVersion=void 0:s instanceof A&&(s.version=n?.version,s.digest=n?.digest);}}async selectCoins(t,e,i="0x2::SUI::SUI"){let n=[],s=0,o=!0,c=null;for(;o&&s<e;){let h=await this.currentClient.getCoins({owner:t,coinType:i,cursor:c});h.data.sort((a,m)=>parseInt(m.balance)-parseInt(a.balance));for(let a of h.data)if(n.push({objectId:a.coinObjectId,digest:a.digest,version:a.version,balance:a.balance}),s=s+parseInt(a.balance),s>=e)break;c=h.nextCursor,o=h.hasNextPage;}if(!n.length)throw new Error("No valid coins found for the transaction.");return n}};var k=class{constructor(t){let{mnemonics:e,secretKey:i,networkType:n}=t;this.accountManager=new f({mnemonics:e,secretKey:i});let s;"fullnodeUrls"in t?s={fullnodeUrls:t.fullnodeUrls}:"suiClients"in t?s={suiClients:t.suiClients}:s={fullnodeUrls:[getFullnodeUrl(n??"mainnet")]},this.suiInteractor=new b(s);}createTxBlock(){let t=new u;return t.setSender(this.accountManager.currentAddress),t}getKeypair(t){return this.accountManager.getKeyPair(t)}switchAccount(t){this.accountManager.switchAccount(t);}getAddress(t){return this.accountManager.getAddress(t)}get currentAddress(){return this.accountManager.currentAddress}async getBalance(t,e){let i=this.accountManager.getAddress(e);return this.suiInteractor.currentClient.getBalance({owner:i,coinType:t})}get client(){return this.suiInteractor.currentClient}async getObjects(t,e){return this.suiInteractor.getObjects(t,e)}async updateObjects(t){return this.suiInteractor.updateObjects(t)}async signTxn(t,e){t instanceof u&&t.setSender(this.getAddress(e));let i=t instanceof u?t.txBlock:t,n=i instanceof Transaction?await i.build({client:this.client}):i;return await this.getKeypair(e).signTransaction(n)}async signAndSendTxn(t,e){let{bytes:i,signature:n}=await this.signTxn(t,e);return this.suiInteractor.sendTx(i,n)}async dryRunTxn(t,e){t instanceof u&&t.setSender(this.getAddress(e));let i=t instanceof u?t.txBlock:t,n=i instanceof Transaction?await i.build({client:this.client}):i;return this.suiInteractor.dryRunTx(n)}async transferSui(t,e,i=!0,n){let s=new u;return s.transferSui(t,e),i?await this.signAndSendTxn(s,n):s}async transferSuiToMany(t,e,i=!0,n){let s=new u;return s.transferSuiToMany(t,e),i?await this.signAndSendTxn(s,n):s}async transferCoinToMany(t,e,i,n=!0,s){let o=new u,c=this.accountManager.getAddress(s),h=e.reduce((m,g)=>m+g,0),a=await this.suiInteractor.selectCoins(c,h,i);return o.transferCoinToMany(a.map(m=>m.objectId),c,t,e),n?await this.signAndSendTxn(o,s):o}async transferCoin(t,e,i,n=!0,s){return this.transferCoinToMany([t],[e],i,n,s)}async transferObjects(t,e,i=!0,n){let s=new u;return s.transferObjects(t,e),i?await this.signAndSendTxn(s,n):s}async moveCall(t){let{target:e,arguments:i=[],typeArguments:n=[],derivePathParams:s}=t,o=new u;return o.moveCall(e,i,n),this.signAndSendTxn(o,s)}async selectCoinsWithAmount(t,e,i){return i=i||this.accountManager.currentAddress,await this.suiInteractor.selectCoins(i,t,e)}async stakeSui(t,e,i=!0,n){let s=new u;return s.stakeSui(t,e),i?await this.signAndSendTxn(s,n):s}async inspectTxn(t,e){let i=t instanceof u?t.txBlock:t;return this.suiInteractor.currentClient.devInspectTransactionBlock({transactionBlock:i,sender:this.getAddress(e)})}};function N(r){let t=fromB64(r);if(t.length!==32&&t.length!==33)throw "invalid pubkey length";return t=t.length===33?t.slice(1):t,new Ed25519PublicKey(t)}var j=class r{constructor(t,e){this.pksWeightPairs=t,this.threshold=e,this.multiSigPublicKey=MultiSigPublicKey.fromPublicKeys({threshold:this.threshold,publicKeys:this.pksWeightPairs});}static fromRawEd25519PublicKeys(t,e,i){let n=t.map((s,o)=>({publicKey:N(s),weight:e[o]}));return new r(n,i)}multiSigAddress(){return this.multiSigPublicKey.toSuiAddress()}combinePartialSigs(t){return this.multiSigPublicKey.combinePartialSignatures(t)}};
14
14
 
15
- export { x as MultiSigClient, S as SuiAccountManager, g as SuiInteractor, O as SuiKit, c as SuiTxBlock };
15
+ export { j as MultiSigClient, f as SuiAccountManager, b as SuiInteractor, k as SuiKit, u as SuiTxBlock };
@@ -5,14 +5,19 @@ import { type SuiTransactionBlockResponse, type SuiObjectDataOptions, type SuiOb
5
5
  * Encapsulates all functions that interact with the sui sdk
6
6
  */
7
7
  export declare class SuiInteractor {
8
- readonly clients: SuiClient[];
8
+ private clients;
9
9
  currentClient: SuiClient;
10
- readonly fullNodes: string[];
10
+ private fullNodes;
11
11
  constructor(params: Partial<SuiInteractorParams>);
12
12
  switchToNextClient(): void;
13
+ switchFullNodes(fullNodes: string[]): void;
14
+ get currentFullNode(): string;
13
15
  sendTx(transactionBlock: Uint8Array | string, signature: string | string[]): Promise<SuiTransactionBlockResponse>;
14
16
  dryRunTx(transactionBlock: Uint8Array): Promise<DryRunTransactionBlockResponse>;
15
- getObjects(ids: string[], options?: SuiObjectDataOptions): Promise<SuiObjectData[]>;
17
+ getObjects(ids: string[], options?: SuiObjectDataOptions & {
18
+ batchSize?: number;
19
+ switchClientDelay?: number;
20
+ }): Promise<SuiObjectData[]>;
16
21
  getObject(id: string, options?: SuiObjectDataOptions): Promise<SuiObjectData>;
17
22
  /**
18
23
  * @description Update objects in a batch
@@ -1 +1,2 @@
1
1
  export declare const delay: (ms: number) => Promise<unknown>;
2
+ export declare const batch: <T>(arr: T[], size: number) => T[][];
package/dist/suiKit.d.ts CHANGED
@@ -46,10 +46,13 @@ export declare class SuiKit {
46
46
  * @param derivePathParams, such as { accountIndex: 2, isExternal: false, addressIndex: 10 }, comply with the BIP44 standard
47
47
  */
48
48
  getAddress(derivePathParams?: DerivePathParams): string;
49
- currentAddress(): string;
49
+ get currentAddress(): string;
50
50
  getBalance(coinType?: string, derivePathParams?: DerivePathParams): Promise<import("@mysten/sui/client").CoinBalance>;
51
- client(): import("@mysten/sui/client").SuiClient;
52
- getObjects(objectIds: string[], options?: SuiObjectDataOptions): Promise<import("@mysten/sui/client").SuiObjectData[]>;
51
+ get client(): import("@mysten/sui/client").SuiClient;
52
+ getObjects(objectIds: string[], options?: SuiObjectDataOptions & {
53
+ batchSize?: number;
54
+ switchClientDelay?: number;
55
+ }): Promise<import("@mysten/sui/client").SuiObjectData[]>;
53
56
  /**
54
57
  * @description Update objects in a batch
55
58
  * @param suiObjects
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@scallop-io/sui-kit",
3
- "version": "1.4.0-alpha.1",
3
+ "version": "1.4.0-alpha.3",
4
4
  "description": "Toolkit for interacting with SUI network",
5
5
  "keywords": [
6
6
  "sui",
@@ -1,6 +1,6 @@
1
1
  import { SuiInteractorParams } from 'src/types';
2
2
  import { SuiOwnedObject, SuiSharedObject } from '../suiModel';
3
- import { delay } from './util';
3
+ import { batch, delay } from './util';
4
4
  import {
5
5
  type SuiTransactionBlockResponseOptions,
6
6
  type SuiTransactionBlockResponse,
@@ -15,9 +15,9 @@ import {
15
15
  * Encapsulates all functions that interact with the sui sdk
16
16
  */
17
17
  export class SuiInteractor {
18
- public readonly clients: SuiClient[] = [];
18
+ private clients: SuiClient[] = [];
19
19
  public currentClient: SuiClient;
20
- public readonly fullNodes: string[] = [];
20
+ private fullNodes: string[] = [];
21
21
 
22
22
  constructor(params: Partial<SuiInteractorParams>) {
23
23
  if ('fullnodeUrls' in params) {
@@ -37,6 +37,28 @@ export class SuiInteractor {
37
37
  this.clients[(currentClientIdx + 1) % this.clients.length];
38
38
  }
39
39
 
40
+ switchFullNodes(fullNodes: string[]) {
41
+ if (fullNodes.length === 0) {
42
+ throw new Error('fullNodes cannot be empty');
43
+ }
44
+ this.fullNodes = fullNodes;
45
+ this.clients = fullNodes.map((url) => new SuiClient({ url }));
46
+ this.currentClient = this.clients[0];
47
+ }
48
+
49
+ get currentFullNode() {
50
+ if (this.fullNodes.length === 0) {
51
+ throw new Error('No full nodes available');
52
+ }
53
+
54
+ const clientIdx = this.clients.indexOf(this.currentClient);
55
+ if (clientIdx === -1) {
56
+ throw new Error('Current client not found');
57
+ }
58
+
59
+ return this.fullNodes[clientIdx];
60
+ }
61
+
40
62
  async sendTx(
41
63
  transactionBlock: Uint8Array | string,
42
64
  signature: string | string[]
@@ -86,7 +108,10 @@ export class SuiInteractor {
86
108
 
87
109
  async getObjects(
88
110
  ids: string[],
89
- options?: SuiObjectDataOptions
111
+ options?: SuiObjectDataOptions & {
112
+ batchSize?: number;
113
+ switchClientDelay?: number;
114
+ }
90
115
  ): Promise<SuiObjectData[]> {
91
116
  const opts: SuiObjectDataOptions = options ?? {
92
117
  showContent: true,
@@ -95,26 +120,41 @@ export class SuiInteractor {
95
120
  showOwner: true,
96
121
  };
97
122
 
98
- for (const clientIdx in this.clients) {
99
- try {
100
- const objects = await this.clients[clientIdx].multiGetObjects({
101
- ids,
102
- options: opts,
103
- });
104
- const parsedObjects = objects
105
- .map((object) => {
106
- return object.data;
107
- })
108
- .filter((object) => object !== null && object !== undefined);
109
- return parsedObjects as SuiObjectData[];
110
- } catch (err) {
111
- await delay(2000);
112
- console.warn(
113
- `Failed to get objects with fullnode ${this.fullNodes[clientIdx]}: ${err}`
123
+ const batchIds = batch(ids, Math.max(options?.batchSize ?? 50, 50));
124
+ const results: SuiObjectData[] = [];
125
+ let lastError = null;
126
+
127
+ for (const batch of batchIds) {
128
+ for (const clientIdx in this.clients) {
129
+ try {
130
+ const objects = await this.clients[clientIdx].multiGetObjects({
131
+ ids: batch,
132
+ options: opts,
133
+ });
134
+ const parsedObjects = objects
135
+ .map((object) => {
136
+ return object.data;
137
+ })
138
+ .filter((object) => object !== null && object !== undefined);
139
+ results.push(...(parsedObjects as SuiObjectData[]));
140
+ lastError = null;
141
+ break; // Exit the client loop if successful
142
+ } catch (err) {
143
+ lastError = err instanceof Error ? err : new Error(String(err));
144
+ await delay(options?.switchClientDelay ?? 2000);
145
+ console.warn(
146
+ `Failed to get objects with fullnode ${this.fullNodes[clientIdx]}: ${err}`
147
+ );
148
+ }
149
+ }
150
+ if (lastError) {
151
+ throw new Error(
152
+ `Failed to get objects with all fullnodes: ${lastError}`
114
153
  );
115
154
  }
116
155
  }
117
- throw new Error('Failed to get objects with all fullnodes');
156
+
157
+ return results;
118
158
  }
119
159
 
120
160
  async getObject(id: string, options?: SuiObjectDataOptions) {
@@ -1,2 +1,10 @@
1
1
  export const delay = (ms: number) =>
2
2
  new Promise((resolve) => setTimeout(resolve, ms));
3
+
4
+ export const batch = <T>(arr: T[], size: number): T[][] => {
5
+ const batches = [];
6
+ for (let i = 0; i < arr.length; i += size) {
7
+ batches.push(arr.slice(i, i + size));
8
+ }
9
+ return batches;
10
+ };
package/src/suiKit.ts CHANGED
@@ -96,7 +96,7 @@ export class SuiKit {
96
96
  return this.accountManager.getAddress(derivePathParams);
97
97
  }
98
98
 
99
- currentAddress() {
99
+ get currentAddress() {
100
100
  return this.accountManager.currentAddress;
101
101
  }
102
102
 
@@ -105,11 +105,17 @@ export class SuiKit {
105
105
  return this.suiInteractor.currentClient.getBalance({ owner, coinType });
106
106
  }
107
107
 
108
- client() {
108
+ get client() {
109
109
  return this.suiInteractor.currentClient;
110
110
  }
111
111
 
112
- async getObjects(objectIds: string[], options?: SuiObjectDataOptions) {
112
+ async getObjects(
113
+ objectIds: string[],
114
+ options?: SuiObjectDataOptions & {
115
+ batchSize?: number;
116
+ switchClientDelay?: number;
117
+ }
118
+ ) {
113
119
  return this.suiInteractor.getObjects(objectIds, options);
114
120
  }
115
121
 
@@ -131,7 +137,7 @@ export class SuiKit {
131
137
  const txBlock = tx instanceof SuiTxBlock ? tx.txBlock : tx;
132
138
  const txBytes =
133
139
  txBlock instanceof Transaction
134
- ? await txBlock.build({ client: this.client() })
140
+ ? await txBlock.build({ client: this.client })
135
141
  : txBlock;
136
142
  const keyPair = this.getKeypair(derivePathParams);
137
143
  return await keyPair.signTransaction(txBytes);
@@ -155,7 +161,7 @@ export class SuiKit {
155
161
  const txBlock = tx instanceof SuiTxBlock ? tx.txBlock : tx;
156
162
  const txBytes =
157
163
  txBlock instanceof Transaction
158
- ? await txBlock.build({ client: this.client() })
164
+ ? await txBlock.build({ client: this.client })
159
165
  : txBlock;
160
166
  return this.suiInteractor.dryRunTx(txBytes);
161
167
  }