@scallop-io/sui-kit 2.1.0 → 2.2.0
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 +6 -6
- package/dist/index.cjs +11 -11
- package/dist/index.d.cts +69 -69
- package/dist/index.d.ts +69 -69
- package/dist/index.js +7 -7
- package/package.json +163 -164
- package/src/index.ts +11 -11
- package/src/libs/multiSig/client.ts +35 -35
- package/src/libs/multiSig/index.ts +1 -1
- package/src/libs/multiSig/publickey.ts +8 -8
- package/src/libs/suiAccountManager/crypto.ts +4 -4
- package/src/libs/suiAccountManager/index.ts +82 -82
- package/src/libs/suiAccountManager/keypair.ts +13 -13
- package/src/libs/suiAccountManager/util.ts +20 -20
- package/src/libs/suiInteractor/index.ts +6 -6
- package/src/libs/suiInteractor/suiInteractor.ts +279 -272
- package/src/libs/suiInteractor/util.ts +6 -6
- package/src/libs/suiModel/index.ts +2 -2
- package/src/libs/suiModel/suiOwnedObject.ts +57 -57
- package/src/libs/suiModel/suiSharedObject.ts +27 -27
- package/src/libs/suiTxBuilder/index.ts +303 -302
- package/src/libs/suiTxBuilder/util.ts +185 -183
- package/src/suiKit.ts +422 -410
- package/src/types/index.ts +71 -76
package/dist/index.js
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import { SUI_SYSTEM_STATE_OBJECT_ID, normalizeStructTag, SUI_TYPE_ARG, isValidSuiAddress, normalizeSuiAddress, isValidSuiObjectId, normalizeSuiObjectId } from '@mysten/sui/utils';
|
|
2
|
-
export * from '@mysten/sui/utils';
|
|
3
1
|
import { Transaction, Inputs, getPureBcsSchema } from '@mysten/sui/transactions';
|
|
4
2
|
export * from '@mysten/sui/transactions';
|
|
3
|
+
import { SUI_SYSTEM_STATE_OBJECT_ID, normalizeStructTag, SUI_TYPE_ARG, isValidSuiAddress, normalizeSuiAddress, isValidSuiObjectId, normalizeSuiObjectId } from '@mysten/sui/utils';
|
|
4
|
+
export * from '@mysten/sui/utils';
|
|
5
|
+
import { MultiSigPublicKey } from '@mysten/sui/multisig';
|
|
6
|
+
import { fromBase64, fromHex, SerializedBcs, isSerializedBcs, bcs } from '@mysten/bcs';
|
|
5
7
|
import { Ed25519Keypair, Ed25519PublicKey } from '@mysten/sui/keypairs/ed25519';
|
|
6
|
-
import {
|
|
8
|
+
import { SUI_PRIVATE_KEY_PREFIX, decodeSuiPrivateKey } from '@mysten/sui/cryptography';
|
|
7
9
|
import { generateMnemonic } from '@scure/bip39';
|
|
8
10
|
import { wordlist } from '@scure/bip39/wordlists/english';
|
|
9
|
-
import { SUI_PRIVATE_KEY_PREFIX, decodeSuiPrivateKey } from '@mysten/sui/cryptography';
|
|
10
11
|
import { SuiGrpcClient } from '@mysten/sui/grpc';
|
|
11
|
-
import { MultiSigPublicKey } from '@mysten/sui/multisig';
|
|
12
12
|
|
|
13
|
-
var Y=(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=Y(t);return Ed25519Keypair.deriveKeypair(r,e)};var X=r=>/^0x[0-9a-fA-F]+$|^[0-9a-fA-F]+$/.test(r),H=r=>/^[a-zA-Z0-9+/]+={0,2}$/g.test(r),B=r=>{if(X(r))return fromHex(r);if(H(r))return fromBase64(r);throw new Error("The string is not a valid hex or base64 string.")},O=32,L=64,w=r=>{if(r.length===L)return r.slice(0,O);if(r.length===O+1&&r[0]===0)return r.slice(1);if(r.length===O)return r;throw new Error("invalid secret key")};var I=(r=24)=>generateMnemonic(wordlist,r===12?128:256);var b=class{mnemonics;secretKey;currentKeyPair;currentAddress;constructor({mnemonics:t,secretKey:e}={}){this.mnemonics=t||"",this.secretKey=e||"",!this.mnemonics&&!this.secretKey&&(this.mnemonics=I(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(w(e))}return Ed25519Keypair.fromSecretKey(w(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 ct=["u8","u16","u32","u64","u128","u256","bool","address"];function ut(r){if(!ct.includes(r))throw new Error(`Invalid SimpleBcsType: ${r}`);return {$kind:r}}var lt=r=>{if(typeof r=="string"&&isValidSuiObjectId(r))return "object";if(typeof r=="number"||typeof r=="bigint")return "u64";if(typeof r=="boolean")return "bool"};function U(r){return typeof r=="number"||typeof r=="bigint"||typeof r=="string"&&!isValidSuiAddress(r)&&!isNaN(Number(r))}function ht(r){return r!==null&&typeof r=="object"&&"vecType"in r&&"value"in r?!0:!!Array.isArray(r)}function dt(r){return typeof r=="object"&&"digest"in r&&"version"in r&&"objectId"in r}function mt(r){return typeof r=="object"&&"objectId"in r&&"initialSharedVersion"in r&&"mutable"in r}function E(r,t,e){if(t.length===0)throw new Error("Transaction builder error: Empty array is not allowed");let i=lt(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)):d(r,a));return r.makeMoveVec({elements:o})}else if(typeof e=="string"&&!n.test(e)&&!s.test(e)){let o=ut(e),a=getPureBcsSchema(o);if(!a)throw new Error(`Unknown type: ${e}`);return r.pure(bcs.vector(a).serialize(t))}else {let o=t.map(a=>d(r,a));return r.makeMoveVec({elements:o,type:e})}}function y(r,t){return t.map(e=>e instanceof SerializedBcs||isSerializedBcs(e)?r.pure(e):ht(e)?"vecType"in e?E(r,e.value,e.vecType):E(r,e):U(e)?p(r,[e])[0]:d(r,e))}function g(r,t){return typeof t=="string"&&isValidSuiAddress(t)?r.pure.address(normalizeSuiAddress(t)):y(r,[t])[0]}function d(r,t){if(typeof t=="string")return r.object(t);if(dt(t))return r.objectRef(t);if(mt(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 p(r,t){return t.map(e=>U(e)?r.pure.u64(e):y(r,[e])[0])}var V=(r,t)=>{let e=[];for(let i=0;i<r.length;i+=t)e.push(r.slice(i,i+t));return e};var u=class{txBlock;constructor(t){this.txBlock=t?Transaction.from(t):new Transaction;}get gas(){return this.txBlock.gas}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=>d(this.txBlock,i)),g(this.txBlock,e))}splitCoins(t,e){let i=this.txBlock.splitCoins(d(this.txBlock,t),p(this.txBlock,e));return e.map((n,s)=>i[s])}mergeCoins(t,e){let i=d(this.txBlock,t),n=e.map(s=>d(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,p(this.txBlock,e));return t.map(s=>g(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{splitedCoins:i,mergedCoin:n}=this.splitMultiCoins(t,p(this.txBlock,[e]));return [i,n]}splitSUIFromGas(t){return this.txBlock.splitCoins(this.txBlock.gas,p(this.txBlock,t))}splitMultiCoins(t,e){if(t.length===0)throw new Error("takeAmountFromCoins: coins array is empty");let i=V(t.slice(1),511),n=d(this.txBlock,t[0]);for(let o of i){let a=o.map(m=>d(this.txBlock,m));this.txBlock.mergeCoins(n,a);}return {splitedCoins:this.txBlock.splitCoins(n,p(this.txBlock,e)),mergedCoin:n}}transferCoinToMany(t,e,i,n){if(i.length!==n.length)throw new Error("transferCoinToMany: recipients.length !== amounts.length");let s=t.map(c=>d(this.txBlock,c)),{splitedCoins:o,mergedCoin:a}=this.splitMultiCoins(s,p(this.txBlock,n));return i.map(c=>g(this.txBlock,c)).forEach((c,h)=>{this.txBlock.transferObjects([o[h]],c);}),this.txBlock.transferObjects([a],g(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,p(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,g(this.txBlock,e)])})}};var A=class{objectId;version;digest;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.Transaction??t.FailedTransaction;if(!e)throw new Error("Bad transaction response!");let i=e.effects;if(!i)throw new Error("Transaction response has no effects!");for(let n of i.changedObjects)if(n.objectId===this.objectId&&n.outputDigest){this.digest=n.outputDigest,this.version=n.outputVersion??void 0;return}throw new Error("Could not find object in transaction response!")}};var x=class{objectId;initialSharedVersion;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)),$=(r,t)=>{let e=[];for(let i=0;i<r.length;i+=t)e.push(r.slice(i,i+t));return e};var _=50;function k(r,t){return {baseUrl:r,network:t}}function T(r){switch(r){case"mainnet":return "https://fullnode.mainnet.sui.io:443";case"testnet":return "https://fullnode.testnet.sui.io:443";case"devnet":return "https://fullnode.devnet.sui.io:443";case"localnet":return "http://127.0.0.1:9000";default:throw new Error(`Unknown network: ${r}`)}}var f=class{clients=[];currentClient;fullNodes=[];network;constructor(t){this.network="mainnet","fullnodeUrls"in t&&t.fullnodeUrls?(this.network=t.network??"mainnet",this.fullNodes=t.fullnodeUrls,this.clients=this.fullNodes.map(e=>new SuiGrpcClient(k(e,this.network)))):"suiClients"in t&&t.suiClients?this.clients=t.suiClients:(this.fullNodes=[T(this.network)],this.clients=[new SuiGrpcClient(k(this.fullNodes[0],this.network))]),this.currentClient=this.clients[0];}switchToNextClient(){let t=this.clients.indexOf(this.currentClient);this.currentClient=this.clients[(t+1)%this.clients.length];}switchFullNodes(t,e){if(t.length===0)throw new Error("fullNodes cannot be empty");this.fullNodes=t,e&&(this.network=e),this.clients=t.map(i=>new SuiGrpcClient(k(i,this.network))),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=typeof t=="string"?Uint8Array.from(Buffer.from(t,"base64")):t,n=Array.isArray(e)?e:[e];for(let s in this.clients)try{return await this.clients[s].core.executeTransaction({transaction:i,signatures:n,include:{balanceChanges:!0,effects:!0,events:!0,objectTypes:!0}})}catch(o){console.warn(`Failed to send transaction with fullnode ${this.fullNodes[s]}: ${o}`),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].core.simulateTransaction({transaction:t,include:{effects:!0,events:!0,balanceChanges:!0,commandResults:!0}})}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?.include??{content:!0,json:!0},n=$(t,Math.max(e?.batchSize??_,_)),s=[],o=null;for(let a of n){for(let m in this.clients)try{let h=(await this.clients[m].core.getObjects({objectIds:a,include:i})).objects.map(l=>l instanceof Error?null:l).filter(l=>l!==null);s.push(...h),o=null;break}catch(c){o=c instanceof Error?c:new Error(String(c)),await P(e?.switchClientDelay??2e3),console.warn(`Failed to get objects with fullnode ${this.fullNodes[m]}: ${c}`);}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);if(s instanceof x){let o=n.owner;o&&typeof o=="object"&&"Shared"in o?s.initialSharedVersion=o.Shared.initialSharedVersion:s.initialSharedVersion=void 0;}else 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,a=null;for(;o&&s<e;){let{objects:m,hasNextPage:c,cursor:h}=await this.currentClient.core.listCoins({owner:t,coinType:i,cursor:a});m.sort((l,W)=>parseInt(W.balance)-parseInt(l.balance));for(let l of m)if(n.push({objectId:l.objectId,digest:l.digest,version:l.version,balance:l.balance}),s=s+parseInt(l.balance),s>=e)break;a=h,o=c;}if(!n.length)throw new Error("No valid coins found for the transaction.");return n}};var v=class{accountManager;suiInteractor;constructor(t){let{mnemonics:e,secretKey:i,networkType:n}=t;this.accountManager=new b({mnemonics:e,secretKey:i});let s=n??"mainnet",o;"fullnodeUrls"in t?o={fullnodeUrls:t.fullnodeUrls,network:s}:"suiClients"in t?o={suiClients:t.suiClients}:o={fullnodeUrls:[T(s)],network:s},this.suiInteractor=new f(o);}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),{balance:n}=await this.suiInteractor.currentClient.core.getBalance({owner:i,coinType:t});return n}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 Uint8Array?i:await i.build({client:this.client});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 Uint8Array?i:await i.build({client:this.client});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,a=this.accountManager.getAddress(s),m=e.reduce((c,h)=>c+h,0);if(normalizeStructTag(i)===normalizeStructTag(SUI_TYPE_ARG))o.transferSuiToMany(t,e);else {let c=await this.suiInteractor.selectCoins(a,m,i);o.transferCoinToMany(c.map(h=>"objectId"in h?o.objectRef(h):h),a,t,e);}return 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){t instanceof u&&t.setSender(this.getAddress(e));let i=t instanceof u?t.txBlock:t,n=i instanceof Uint8Array?i:await i.build({client:this.client});return this.suiInteractor.currentClient.core.simulateTransaction({transaction:n,include:{effects:!0,events:!0,balanceChanges:!0,commandResults:!0}})}};function G(r){let t=fromBase64(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{pksWeightPairs;threshold;multiSigPublicKey;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:G(s),weight:e[o]}));return new r(n,i)}multiSigAddress(){return this.multiSigPublicKey.toSuiAddress()}combinePartialSigs(t){return this.multiSigPublicKey.combinePartialSignatures(t)}};
|
|
13
|
+
function B(r){let t=fromBase64(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{pksWeightPairs;threshold;multiSigPublicKey;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:B(s),weight:e[o]}));return new r(n,i)}multiSigAddress(){return this.multiSigPublicKey.toSuiAddress()}combinePartialSigs(t){return this.multiSigPublicKey.combinePartialSignatures(t)}};var I=(r=24)=>generateMnemonic(wordlist,r===12?128:256);var L=(r={})=>{let{accountIndex:t=0,isExternal:e=false,addressIndex:i=0}=r;return `m/44'/784'/${t}'/${e?1:0}'/${i}'`},S=(r,t={})=>{let e=L(t);return Ed25519Keypair.deriveKeypair(r,e)};var tt=r=>/^0x[0-9a-fA-F]+$|^[0-9a-fA-F]+$/.test(r),et=r=>/^[a-zA-Z0-9+/]+={0,2}$/g.test(r),K=r=>{if(tt(r))return fromHex(r);if(et(r))return fromBase64(r);throw new Error("The string is not a valid hex or base64 string.")},O=32,rt=64,w=r=>{if(r.length===rt)return r.slice(0,O);if(r.length===O+1&&r[0]===0)return r.slice(1);if(r.length===O)return r;throw new Error("invalid secret key")};var b=class{mnemonics;secretKey;currentKeyPair;currentAddress;constructor({mnemonics:t,secretKey:e}={}){this.mnemonics=t||"",this.secretKey=e||"",!this.mnemonics&&!this.secretKey&&(this.mnemonics=I(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(w(e))}return Ed25519Keypair.fromSecretKey(w(K(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 y=class{objectId;version;digest;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.Transaction??t.FailedTransaction;if(!e)throw new Error("Bad transaction response!");let i=e.effects;if(!i)throw new Error("Transaction response has no effects!");for(let n of i.changedObjects)if(n.objectId===this.objectId&&n.outputDigest){this.digest=n.outputDigest,this.version=n.outputVersion??void 0;return}throw new Error("Could not find object in transaction response!")}};var A=class{objectId;initialSharedVersion;constructor(t){this.objectId=t.objectId,this.initialSharedVersion=t.initialSharedVersion;}asCallArg(t=false){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)),E=(r,t)=>{let e=[];for(let i=0;i<r.length;i+=t)e.push(r.slice(i,i+t));return e};var D=50;function k(r,t){return {baseUrl:r,network:t}}function x(r){switch(r){case "mainnet":return "https://fullnode.mainnet.sui.io:443";case "testnet":return "https://fullnode.testnet.sui.io:443";case "devnet":return "https://fullnode.devnet.sui.io:443";case "localnet":return "http://127.0.0.1:9000";default:throw new Error(`Unknown network: ${r}`)}}var g=class{clients=[];currentClient;fullNodes=[];network;constructor(t){this.network="mainnet","fullnodeUrls"in t&&t.fullnodeUrls?(this.network=t.network??"mainnet",this.fullNodes=t.fullnodeUrls,this.clients=this.fullNodes.map(e=>new SuiGrpcClient(k(e,this.network)))):"suiClients"in t&&t.suiClients?this.clients=t.suiClients:(this.fullNodes=[x(this.network)],this.clients=[new SuiGrpcClient(k(this.fullNodes[0],this.network))]),this.currentClient=this.clients[0];}getClient(t){if(t<0||t>=this.clients.length)throw new Error("Client index out of bounds");return this.clients[t]}switchToNextClient(){let t=this.clients.indexOf(this.currentClient);this.currentClient=this.clients[(t+1)%this.clients.length];}switchFullNodes(t,e){if(t.length===0)throw new Error("fullNodes cannot be empty");this.fullNodes=t,e&&(this.network=e),this.clients=t.map(i=>new SuiGrpcClient(k(i,this.network))),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=typeof t=="string"?Uint8Array.from(Buffer.from(t,"base64")):t,n=Array.isArray(e)?e:[e];for(let s in this.clients)try{return await this.clients[s].core.executeTransaction({transaction:i,signatures:n,include:{balanceChanges:!0,effects:!0,events:!0,objectTypes:!0}})}catch(o){console.warn(`Failed to send transaction with fullnode ${this.fullNodes[s]}: ${o}`),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].core.simulateTransaction({transaction:t,include:{effects:!0,events:!0,balanceChanges:!0,commandResults:!0}})}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?.include??{content:true,json:true},n=E(t,Math.max(e?.batchSize??D,D)),s=[],o=null;for(let a of n){for(let m in this.clients)try{let h=(await this.clients[m].core.getObjects({objectIds:a,include:i})).objects.map(l=>l instanceof Error?null:l).filter(l=>l!==null);s.push(...h),o=null;break}catch(c){o=c instanceof Error?c:new Error(String(c)),await P(e?.switchClientDelay??2e3),console.warn(`Failed to get objects with fullnode ${this.fullNodes[m]}: ${c}`);}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);if(s instanceof A){let o=n.owner;o&&typeof o=="object"&&"Shared"in o?s.initialSharedVersion=o.Shared.initialSharedVersion:s.initialSharedVersion=void 0;}else s instanceof y&&(s.version=n?.version,s.digest=n?.digest);}}async selectCoins(t,e,i="0x2::SUI::SUI"){let n=[],s=0,o=true,a=null;for(;o&&s<e;){let{objects:m,hasNextPage:c,cursor:h}=await this.currentClient.core.listCoins({owner:t,coinType:i,cursor:a});m.sort((l,W)=>parseInt(W.balance,10)-parseInt(l.balance,10));for(let l of m)if(n.push({objectId:l.objectId,digest:l.digest,version:l.version,balance:l.balance}),s=s+parseInt(l.balance,10),s>=e)break;a=h,o=c;}if(!n.length)throw new Error("No valid coins found for the transaction.");return n}};var ht=["u8","u16","u32","u64","u128","u256","bool","address"];function dt(r){if(!ht.includes(r))throw new Error(`Invalid SimpleBcsType: ${r}`);return {$kind:r}}var mt=r=>{if(typeof r=="string"&&isValidSuiObjectId(r))return "object";if(typeof r=="number"||typeof r=="bigint")return "u64";if(typeof r=="boolean")return "bool"};function $(r){return typeof r=="number"||typeof r=="bigint"||typeof r=="string"&&!isValidSuiAddress(r)&&!Number.isNaN(Number(r))}function pt(r){return r!==null&&typeof r=="object"&&"vecType"in r&&"value"in r?true:!!Array.isArray(r)}function gt(r){return typeof r=="object"&&"digest"in r&&"version"in r&&"objectId"in r}function ft(r){return typeof r=="object"&&"objectId"in r&&"initialSharedVersion"in r&&"mutable"in r}function U(r,t,e){if(t.length===0)throw new Error("Transaction builder error: Empty array is not allowed");let i=mt(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)):d(r,a));return r.makeMoveVec({elements:o})}else if(typeof e=="string"&&!n.test(e)&&!s.test(e)){let o=dt(e),a=getPureBcsSchema(o);if(!a)throw new Error(`Unknown type: ${e}`);return r.pure(bcs.vector(a).serialize(t))}else {let o=t.map(a=>d(r,a));return r.makeMoveVec({elements:o,type:e})}}function T(r,t){return t.map(e=>e instanceof SerializedBcs||isSerializedBcs(e)?r.pure(e):pt(e)?"vecType"in e?U(r,e.value,e.vecType):U(r,e):$(e)?p(r,[e])[0]:d(r,e))}function f(r,t){return typeof t=="string"&&isValidSuiAddress(t)?r.pure.address(normalizeSuiAddress(t)):T(r,[t])[0]}function d(r,t){if(typeof t=="string")return r.object(t);if(gt(t))return r.objectRef(t);if(ft(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 p(r,t){return t.map(e=>$(e)?r.pure.u64(e):T(r,[e])[0])}var _=(r,t)=>{let e=[];for(let i=0;i<r.length;i+=t)e.push(r.slice(i,i+t));return e};var u=class{txBlock;constructor(t){this.txBlock=t?Transaction.from(t):new Transaction;}get gas(){return this.txBlock.gas}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=>d(this.txBlock,i)),f(this.txBlock,e))}splitCoins(t,e){let i=this.txBlock.splitCoins(d(this.txBlock,t),p(this.txBlock,e));return e.map((n,s)=>i[s])}mergeCoins(t,e){let i=d(this.txBlock,t),n=e.map(s=>d(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=T(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,p(this.txBlock,e));return t.map(s=>f(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{splitedCoins:i,mergedCoin:n}=this.splitMultiCoins(t,p(this.txBlock,[e]));return [i,n]}splitSUIFromGas(t){return this.txBlock.splitCoins(this.txBlock.gas,p(this.txBlock,t))}splitMultiCoins(t,e){if(t.length===0)throw new Error("takeAmountFromCoins: coins array is empty");let i=_(t.slice(1),511),n=d(this.txBlock,t[0]);for(let o of i){let a=o.map(m=>d(this.txBlock,m));this.txBlock.mergeCoins(n,a);}return {splitedCoins:this.txBlock.splitCoins(n,p(this.txBlock,e)),mergedCoin:n}}transferCoinToMany(t,e,i,n){if(i.length!==n.length)throw new Error("transferCoinToMany: recipients.length !== amounts.length");let s=t.map(c=>d(this.txBlock,c)),{splitedCoins:o,mergedCoin:a}=this.splitMultiCoins(s,p(this.txBlock,n));return i.map(c=>f(this.txBlock,c)).forEach((c,h)=>{this.txBlock.transferObjects([o[h]],c);}),this.txBlock.transferObjects([a],f(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,p(this.txBlock,[t]));return this.txBlock.moveCall({target:"0x3::sui_system::request_add_stake",arguments:T(this.txBlock,[this.txBlock.object(SUI_SYSTEM_STATE_OBJECT_ID),i,f(this.txBlock,e)])})}};var v=class{accountManager;suiInteractor;constructor(t){let{mnemonics:e,secretKey:i,networkType:n}=t;this.accountManager=new b({mnemonics:e,secretKey:i});let s=n??"mainnet",o;"fullnodeUrls"in t?o={fullnodeUrls:t.fullnodeUrls,network:s}:"suiClients"in t?o={suiClients:t.suiClients}:o={fullnodeUrls:[x(s)],network:s},this.suiInteractor=new g(o);}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),{balance:n}=await this.suiInteractor.currentClient.core.getBalance({owner:i,coinType:t});return n}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 Uint8Array?i:await i.build({client:this.client});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 Uint8Array?i:await i.build({client:this.client});return this.suiInteractor.dryRunTx(n)}async transferSui(t,e,i=true,n){let s=new u;return s.transferSui(t,e),i?await this.signAndSendTxn(s,n):s}async transferSuiToMany(t,e,i=true,n){let s=new u;return s.transferSuiToMany(t,e),i?await this.signAndSendTxn(s,n):s}async transferCoinToMany(t,e,i,n=true,s){let o=new u,a=this.accountManager.getAddress(s),m=e.reduce((c,h)=>c+h,0);if(normalizeStructTag(i)===normalizeStructTag(SUI_TYPE_ARG))o.transferSuiToMany(t,e);else {let c=await this.suiInteractor.selectCoins(a,m,i);o.transferCoinToMany(c.map(h=>"objectId"in h?o.objectRef(h):h),a,t,e);}return n?await this.signAndSendTxn(o,s):o}async transferCoin(t,e,i,n=true,s){return this.transferCoinToMany([t],[e],i,n,s)}async transferObjects(t,e,i=true,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=true,n){let s=new u;return s.stakeSui(t,e),i?await this.signAndSendTxn(s,n):s}async inspectTxn(t,e){t instanceof u&&t.setSender(this.getAddress(e));let i=t instanceof u?t.txBlock:t,n=i instanceof Uint8Array?i:await i.build({client:this.client});return this.suiInteractor.currentClient.core.simulateTransaction({transaction:n,include:{effects:true,events:true,balanceChanges:true,commandResults:true},checksEnabled:false})}};
|
|
14
14
|
|
|
15
|
-
export { j as MultiSigClient, b as SuiAccountManager,
|
|
15
|
+
export { j as MultiSigClient, b as SuiAccountManager, g as SuiInteractor, v as SuiKit, u as SuiTxBlock, x as getFullnodeUrl };
|
package/package.json
CHANGED
|
@@ -1,166 +1,165 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
}
|
|
2
|
+
"name": "@scallop-io/sui-kit",
|
|
3
|
+
"version": "2.2.0",
|
|
4
|
+
"description": "Toolkit for interacting with SUI network",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"sui",
|
|
7
|
+
"scallop labs",
|
|
8
|
+
"move",
|
|
9
|
+
"blockchain",
|
|
10
|
+
"sui-kit"
|
|
11
|
+
],
|
|
12
|
+
"author": "team@scallop.io",
|
|
13
|
+
"homepage": "https://github.com/scallop-io/sui-kit#readme",
|
|
14
|
+
"bugs": "https://github.com/scallop-io/sui-kit/issues",
|
|
15
|
+
"repository": {
|
|
16
|
+
"type": "git",
|
|
17
|
+
"url": "https://github.com/scallop-io/sui-kit.git"
|
|
18
|
+
},
|
|
19
|
+
"license": "Apache-2.0",
|
|
20
|
+
"publishConfig": {
|
|
21
|
+
"access": "public"
|
|
22
|
+
},
|
|
23
|
+
"engines": {
|
|
24
|
+
"node": ">=22"
|
|
25
|
+
},
|
|
26
|
+
"type": "module",
|
|
27
|
+
"main": "./dist/index.js",
|
|
28
|
+
"types": "./dist/index.d.ts",
|
|
29
|
+
"exports": {
|
|
30
|
+
".": {
|
|
31
|
+
"types": "./dist/index.d.ts",
|
|
32
|
+
"import": "./dist/index.js"
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
"files": [
|
|
36
|
+
"dist",
|
|
37
|
+
"src"
|
|
38
|
+
],
|
|
39
|
+
"scripts": {
|
|
40
|
+
"clean": "rm -rf tsconfig.tsbuildinfo ./dist",
|
|
41
|
+
"build": "npm run build:types && npm run build:prod",
|
|
42
|
+
"build:prod": "tsup --env.NODE_ENV production",
|
|
43
|
+
"build:dev": "tsup",
|
|
44
|
+
"build:types": "tsc --build",
|
|
45
|
+
"watch:tsup": "tsup --watch",
|
|
46
|
+
"watch": "pnpm run clean && pnpm run watch:tsup",
|
|
47
|
+
"test": "pnpm test:typecheck && pnpm test:unit && pnpm test:integration",
|
|
48
|
+
"test:typecheck": "tsc -p ./test",
|
|
49
|
+
"test:unit": "vitest run test/unit --test-timeout=60000",
|
|
50
|
+
"test:gate": "node scripts/check-test-pass-rate.mjs",
|
|
51
|
+
"test:integration": "vitest run test/integration --test-timeout=60000",
|
|
52
|
+
"test:watch": "vitest",
|
|
53
|
+
"test:coverage-unit": "vitest run test/unit --coverage --test-timeout=60000",
|
|
54
|
+
"test:coverage-integration": "vitest run test/integration --coverage --test-timeout=60000",
|
|
55
|
+
"test:coverage": "vitest run --coverage --test-timeout=60000",
|
|
56
|
+
"lint:fix": "biome lint --fix .",
|
|
57
|
+
"format:fix": "biome check --fix .",
|
|
58
|
+
"prepare": "husky install",
|
|
59
|
+
"commit": "commit",
|
|
60
|
+
"release": "standard-version -f",
|
|
61
|
+
"release:major": "standard-version -r major",
|
|
62
|
+
"release:minor": "standard-version -r minor",
|
|
63
|
+
"release:patch": "standard-version -r patch",
|
|
64
|
+
"doc": "typedoc --out docs src/index.ts"
|
|
65
|
+
},
|
|
66
|
+
"dependencies": {
|
|
67
|
+
"@mysten/bcs": "^2.0.1",
|
|
68
|
+
"@scure/bip39": "^1.5.4",
|
|
69
|
+
"assert": "^2.1.0",
|
|
70
|
+
"bech32": "^2.0.0"
|
|
71
|
+
},
|
|
72
|
+
"peerDependencies": {
|
|
73
|
+
"@mysten/sui": "^2.0.0"
|
|
74
|
+
},
|
|
75
|
+
"devDependencies": {
|
|
76
|
+
"@biomejs/biome": "2.5.0",
|
|
77
|
+
"@commitlint/cli": "^18.0.0",
|
|
78
|
+
"@commitlint/config-conventional": "^18.0.0",
|
|
79
|
+
"@commitlint/prompt-cli": "^18.0.0",
|
|
80
|
+
"@mysten/sui": "^2.17.0",
|
|
81
|
+
"@protobuf-ts/grpcweb-transport": "^2.11.1",
|
|
82
|
+
"@protobuf-ts/runtime-rpc": "^2.11.1",
|
|
83
|
+
"@types/chai": "^5.2.2",
|
|
84
|
+
"@types/node": "^20.19.0",
|
|
85
|
+
"@types/tmp": "^0.2.5",
|
|
86
|
+
"@vitest/coverage-v8": "4.1.8",
|
|
87
|
+
"@vitest/expect": "4.1.8",
|
|
88
|
+
"@vitest/runner": "4.1.8",
|
|
89
|
+
"@vitest/spy": "4.1.8",
|
|
90
|
+
"dotenv": "^16.3.1",
|
|
91
|
+
"husky": "^8.0.3",
|
|
92
|
+
"lint-staged": "^15.0.2",
|
|
93
|
+
"prettier": "^3.0.3",
|
|
94
|
+
"standard-version": "^9.5.0",
|
|
95
|
+
"ts-node": "^10.9.1",
|
|
96
|
+
"tsconfig-paths": "^4.2.0",
|
|
97
|
+
"tsup": "^7.2.0",
|
|
98
|
+
"typedoc": "^0.25.2",
|
|
99
|
+
"typescript": "5.5.4",
|
|
100
|
+
"valibot": "^0.36.0",
|
|
101
|
+
"vite": "^8.0.16",
|
|
102
|
+
"vitest": "4.1.8"
|
|
103
|
+
},
|
|
104
|
+
"lint-staged": {
|
|
105
|
+
"**/*.ts": [
|
|
106
|
+
"pnpm run format:fix",
|
|
107
|
+
"pnpm run lint:fix"
|
|
108
|
+
],
|
|
109
|
+
"**/*.json|md": [
|
|
110
|
+
"pnpm run format:fix"
|
|
111
|
+
]
|
|
112
|
+
},
|
|
113
|
+
"husky": {
|
|
114
|
+
"hooks": {
|
|
115
|
+
"pre-commit": "lint-staged"
|
|
116
|
+
}
|
|
117
|
+
},
|
|
118
|
+
"commitlint": {
|
|
119
|
+
"extends": [
|
|
120
|
+
"@commitlint/config-conventional"
|
|
121
|
+
]
|
|
122
|
+
},
|
|
123
|
+
"prettier": {
|
|
124
|
+
"trailingComma": "es5",
|
|
125
|
+
"tabWidth": 2,
|
|
126
|
+
"semi": true,
|
|
127
|
+
"singleQuote": true,
|
|
128
|
+
"useTabs": false,
|
|
129
|
+
"quoteProps": "as-needed",
|
|
130
|
+
"bracketSpacing": true,
|
|
131
|
+
"arrowParens": "always",
|
|
132
|
+
"endOfLine": "lf"
|
|
133
|
+
},
|
|
134
|
+
"eslintConfig": {
|
|
135
|
+
"root": true,
|
|
136
|
+
"env": {
|
|
137
|
+
"browser": true,
|
|
138
|
+
"node": true,
|
|
139
|
+
"es2022": true
|
|
140
|
+
},
|
|
141
|
+
"extends": [
|
|
142
|
+
"eslint:recommended",
|
|
143
|
+
"plugin:@typescript-eslint/eslint-recommended",
|
|
144
|
+
"plugin:prettier/recommended"
|
|
145
|
+
],
|
|
146
|
+
"plugins": [
|
|
147
|
+
"@typescript-eslint",
|
|
148
|
+
"prettier"
|
|
149
|
+
],
|
|
150
|
+
"parser": "@typescript-eslint/parser",
|
|
151
|
+
"rules": {
|
|
152
|
+
"prettier/prettier": "warn",
|
|
153
|
+
"@typescript-eslint/no-explicit-any": "off",
|
|
154
|
+
"no-unused-vars": "off",
|
|
155
|
+
"@typescript-eslint/no-unused-vars": [
|
|
156
|
+
"error",
|
|
157
|
+
{
|
|
158
|
+
"argsIgnorePattern": "^_",
|
|
159
|
+
"varsIgnorePattern": "^_",
|
|
160
|
+
"caughtErrorsIgnorePattern": "^_"
|
|
161
|
+
}
|
|
162
|
+
]
|
|
163
|
+
}
|
|
164
|
+
}
|
|
166
165
|
}
|
package/src/index.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
export * from
|
|
2
|
-
export * from
|
|
3
|
-
export {
|
|
4
|
-
export { SuiAccountManager } from
|
|
5
|
-
export { SuiTxBlock } from './libs/suiTxBuilder/index.js';
|
|
6
|
-
export { MultiSigClient } from './libs/multiSig/index.js';
|
|
1
|
+
export * from "@mysten/sui/transactions";
|
|
2
|
+
export * from "@mysten/sui/utils";
|
|
3
|
+
export { MultiSigClient } from "./libs/multiSig/index.js";
|
|
4
|
+
export { SuiAccountManager } from "./libs/suiAccountManager/index.js";
|
|
7
5
|
export {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
} from
|
|
12
|
-
export
|
|
6
|
+
getFullnodeUrl,
|
|
7
|
+
type SimulateTransactionResponse,
|
|
8
|
+
SuiInteractor,
|
|
9
|
+
} from "./libs/suiInteractor/index.js";
|
|
10
|
+
export { SuiTxBlock } from "./libs/suiTxBuilder/index.js";
|
|
11
|
+
export { SuiKit } from "./suiKit.js";
|
|
12
|
+
export type * from "./types/index.js";
|
|
@@ -1,44 +1,44 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import
|
|
3
|
-
import { ed25519PublicKeyFromBase64 } from
|
|
1
|
+
import type { PublicKey } from "@mysten/sui/cryptography";
|
|
2
|
+
import { MultiSigPublicKey } from "@mysten/sui/multisig";
|
|
3
|
+
import { ed25519PublicKeyFromBase64 } from "./publickey.js";
|
|
4
4
|
|
|
5
5
|
export type PublicKeyWeightPair = {
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
publicKey: PublicKey;
|
|
7
|
+
weight: number;
|
|
8
8
|
};
|
|
9
9
|
|
|
10
10
|
export class MultiSigClient {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
11
|
+
public readonly pksWeightPairs: PublicKeyWeightPair[];
|
|
12
|
+
public readonly threshold: number;
|
|
13
|
+
public readonly multiSigPublicKey: MultiSigPublicKey;
|
|
14
|
+
constructor(pks: PublicKeyWeightPair[], threshold: number) {
|
|
15
|
+
this.pksWeightPairs = pks;
|
|
16
|
+
this.threshold = threshold;
|
|
17
|
+
this.multiSigPublicKey = MultiSigPublicKey.fromPublicKeys({
|
|
18
|
+
threshold: this.threshold,
|
|
19
|
+
publicKeys: this.pksWeightPairs,
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
22
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
23
|
+
static fromRawEd25519PublicKeys(
|
|
24
|
+
rawPublicKeys: string[],
|
|
25
|
+
weights: number[],
|
|
26
|
+
threshold: number,
|
|
27
|
+
): MultiSigClient {
|
|
28
|
+
const pks = rawPublicKeys.map((rawPublicKey, i) => {
|
|
29
|
+
return {
|
|
30
|
+
publicKey: ed25519PublicKeyFromBase64(rawPublicKey),
|
|
31
|
+
weight: weights[i],
|
|
32
|
+
};
|
|
33
|
+
});
|
|
34
|
+
return new MultiSigClient(pks, threshold);
|
|
35
|
+
}
|
|
36
36
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
37
|
+
multiSigAddress(): string {
|
|
38
|
+
return this.multiSigPublicKey.toSuiAddress();
|
|
39
|
+
}
|
|
40
40
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
41
|
+
combinePartialSigs(sigs: string[]): string {
|
|
42
|
+
return this.multiSigPublicKey.combinePartialSignatures(sigs);
|
|
43
|
+
}
|
|
44
44
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export { MultiSigClient } from
|
|
1
|
+
export { MultiSigClient } from "./client.js";
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { fromBase64 } from "@mysten/bcs";
|
|
2
|
+
import type { PublicKey } from "@mysten/sui/cryptography";
|
|
3
|
+
import { Ed25519PublicKey } from "@mysten/sui/keypairs/ed25519";
|
|
4
4
|
|
|
5
5
|
export function ed25519PublicKeyFromBase64(rawPubkey: string): PublicKey {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
6
|
+
let bytes = fromBase64(rawPubkey);
|
|
7
|
+
// raw public keys should either be 32 bytes or 33 bytes (with the first byte being flag)
|
|
8
|
+
if (bytes.length !== 32 && bytes.length !== 33) throw "invalid pubkey length";
|
|
9
|
+
bytes = bytes.length === 33 ? bytes.slice(1) : bytes;
|
|
10
|
+
return new Ed25519PublicKey(bytes);
|
|
11
11
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { generateMnemonic as genMnemonic } from
|
|
2
|
-
import { wordlist } from
|
|
1
|
+
import { generateMnemonic as genMnemonic } from "@scure/bip39";
|
|
2
|
+
import { wordlist } from "@scure/bip39/wordlists/english";
|
|
3
3
|
|
|
4
4
|
export const generateMnemonic = (numberOfWords: 12 | 24 = 24) => {
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
const strength = numberOfWords === 12 ? 128 : 256;
|
|
6
|
+
return genMnemonic(wordlist, strength);
|
|
7
7
|
};
|