@msafe/sui3-sdk 0.0.21 → 0.0.22

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/dist/index.cjs CHANGED
@@ -531,6 +531,7 @@ var MSafeAccount = class _MSafeAccount {
531
531
  };
532
532
  return getAllOwnedObjects(this.suiClient, this.address, filterCoinObjectOptions);
533
533
  }
534
+ // TODO: Calculate the votes
534
535
  async pendingTransaction() {
535
536
  const res = await this.backend.getPendingTransactions({ msafeAddress: this.address });
536
537
  if (!res.pending) {
@@ -548,12 +549,15 @@ var MSafeAccount = class _MSafeAccount {
548
549
  sequenceNumber: pendingTx.sequenceNumber,
549
550
  payload: pendingTx.payload,
550
551
  votes: pendingTx.votes,
552
+ approvalWeight: this.calculateWeightFromVotes(pendingTx.votes),
551
553
  msafeAddress: pendingTx.msafeAddress,
552
554
  rejectDigest: rejectPending?.digest ?? "",
553
555
  rejectPayload: rejectPending?.payload ?? "",
554
- rejectVotes: rejectPending?.votes ?? []
556
+ rejectVotes: rejectPending?.votes ?? [],
557
+ rejectWeight: this.calculateWeightFromVotes(rejectPending?.votes ?? [])
555
558
  };
556
559
  }
560
+ // TODO: Calculate the votes.
557
561
  async historyTransaction(pagination) {
558
562
  return this.backend.getHistoryTransactions({
559
563
  msafeAddress: this.address,
@@ -672,33 +676,41 @@ var MSafeAccount = class _MSafeAccount {
672
676
  dryRunResult
673
677
  };
674
678
  }
675
- async executePendingTx(pending) {
676
- let gotSigs;
677
- let payload;
678
- if (pending.votes.length >= this.info.threshold) {
679
- gotSigs = new Map(pending.votes.map((vote) => [vote.userAddress, vote.signature]));
680
- payload = pending.payload;
681
- } else if (pending.rejectVotes && pending.rejectPayload && pending.rejectVotes?.length >= this.info.threshold) {
682
- gotSigs = new Map(pending.rejectVotes.map((vote) => [vote.userAddress, vote.signature]));
683
- payload = pending.rejectPayload;
684
- } else {
685
- throw new Error("Not enough signatures");
679
+ async executePendingTx(pending, isRejectTx = false) {
680
+ const votes = isRejectTx ? pending.rejectVotes : pending.votes;
681
+ const payload = isRejectTx ? pending.rejectPayload : pending.payload;
682
+ if (this.calculateWeightFromVotes(votes) < this.info.threshold) {
683
+ throw new Error("Not enough signature");
686
684
  }
687
- const sigs = [];
685
+ const sortedSigs = [];
686
+ const gotSigs = new Map(votes.map((vote) => [vote.userAddress, vote.signature]));
688
687
  for (let i = 0; i < this.info.owners.length; i++) {
689
688
  const owner = this.info.owners[i];
690
689
  const signature = gotSigs.get(owner.address);
691
690
  if (signature) {
692
- sigs.push(signature);
691
+ sortedSigs.push(signature);
693
692
  }
694
693
  }
695
- const multiSignature = this.multiSig.combinePartialSignatures(sigs);
694
+ const multiSignature = this.multiSig.combinePartialSignatures(sortedSigs);
696
695
  return this.suiClient.executeTransactionBlock({
697
696
  transactionBlock: HexToUint8Array(payload),
698
697
  signature: multiSignature,
699
698
  options: { showEffects: true }
700
699
  });
701
700
  }
701
+ calculateWeightFromVotes(votes) {
702
+ return this.calculateWeight(votes.map((vote) => vote.userAddress));
703
+ }
704
+ calculateWeight(addressList) {
705
+ let gotWeight = 0;
706
+ for (let i = 0; i < addressList.length; i++) {
707
+ const found = this.info.owners.find((owner) => (0, import_sui3_utils4.isSameAddress)(owner.address, addressList[i]));
708
+ if (found) {
709
+ gotWeight += found.weight;
710
+ }
711
+ }
712
+ return gotWeight;
713
+ }
702
714
  get address() {
703
715
  return this.multiSig.address;
704
716
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/core/CreateHelper.ts","../src/core/MSafeClient.ts","../src/core/AddressBookSDK.ts","../src/core/InvitationSDK.ts","../src/core/MSafeAccount.ts","../src/utils/buffer.ts","../src/utils/crypto.ts","../src/utils/format.ts","../src/utils/coin.ts","../src/utils/sui.ts","../src/utils/iter/iterator.ts","../src/utils/iter/object.ts","../src/core/PublicKeyHelper.ts","../src/globals/MSafeGlobals.ts","../src/backend/BackendImpl.ts","../src/globals/const.ts"],"sourcesContent":["export * from './core';\nexport * from './globals';\nexport * from './types';\nexport * from './utils';\n","import { MultiSigAccount, MultiSigConfig, PublicKeySerde, SigningMessageHelper } from '@msafe/sui3-utils';\nimport { PublicKey, SerializedSignature } from '@mysten/sui.js/cryptography';\n\nimport { PublicKeyHelper } from '@/core/PublicKeyHelper';\nimport { MSafeGlobals } from '@/globals/MSafeGlobals';\nimport { CreateMSafeInfo } from '@/types';\n\nexport class CreateHelper {\n constructor(\n public readonly globals: MSafeGlobals,\n public readonly pkHelper: PublicKeyHelper,\n ) {}\n\n async getPublicKeyBatch(addresses: string[]) {\n return this.pkHelper.getPublicKeyBatch(addresses);\n }\n\n async calculateMSafeAddress(info: CreateMSafeInfo) {\n const msConfig = await this.reduceCreationInfoToRawConfig(info);\n const ms = new MultiSigAccount(msConfig);\n return ms.address;\n }\n\n // Validate the create info and return the msafe address.\n async validateCreateInfo(createInfo: CreateMSafeInfo) {\n // Calculate the sui address will check the multi-sig\n return this.calculateMSafeAddress(createInfo);\n }\n\n async submitMSafeCreation(creationInfo: CreateMSafeInfo) {\n const msafeAddress = await this.validateCreateInfo(creationInfo);\n\n const signingMessage = SigningMessageHelper.createMSafeMessage(msafeAddress);\n const signature = await this.globals.wallet.signPersonalMessage({ messageStr: signingMessage });\n\n await this.submitToBackend(creationInfo, signature.signature);\n return msafeAddress;\n }\n\n private async reduceCreationInfoToRawConfig(info: CreateMSafeInfo): Promise<MultiSigConfig> {\n const publicKeys = await this.getPublicKeyBatch(info.owners.map((owner) => owner.address));\n publicKeys.forEach((pk, i) => {\n if (pk === undefined) {\n throw new Error(`Unknown public key for address: ${info.owners[i].address}`);\n }\n });\n return {\n threshold: info.threshold,\n ownersWithWeight: info.owners.map((owner, i) => ({\n publicKey: publicKeys[i] as PublicKey,\n weight: owner.weight,\n })),\n creationNonce: info.creationNonce,\n };\n }\n\n private async submitToBackend(createInfo: CreateMSafeInfo, signature: SerializedSignature) {\n const pks = await this.pkHelper.getPublicKeyBatch(createInfo.owners.map((owner) => owner.address));\n await this.globals.backend.createMSafeAccount({\n owners: createInfo.owners.map((owner, i) => ({\n address: owner.address,\n weight: owner.weight,\n ...PublicKeySerde.ser(pks[i] as PublicKey),\n })),\n threshold: createInfo.threshold,\n name: createInfo.name, // name validation is deferred to backend\n description: createInfo.description, // description validation is deferred to backend\n creationNonce: createInfo.creationNonce,\n signature,\n });\n }\n}\n","import {\n IMSafeConfig,\n IPagedResult,\n IPageOptions,\n JWTToken,\n SigningMessageHelper,\n UserMSafeStatus,\n} from '@msafe/sui3-utils';\n\nimport { AddressBookSDK } from '@/core/AddressBookSDK';\nimport { CreateHelper } from '@/core/CreateHelper';\nimport { InvitationSDK } from '@/core/InvitationSDK';\nimport { MSafeAccount } from '@/core/MSafeAccount';\nimport { PublicKeyHelper } from '@/core/PublicKeyHelper';\nimport { MSafeConfigOptions, MSafeEnv } from '@/globals/const';\nimport { MSafeGlobals } from '@/globals/MSafeGlobals';\nimport { CreateMSafeInfo } from '@/types';\nimport { IWallet } from '@/types/wallet';\n\nexport class MSafeClient {\n private _creationHelper: CreateHelper | undefined;\n\n private _publicKeyHelper: PublicKeyHelper | undefined;\n\n constructor(public readonly globals: MSafeGlobals) {}\n\n static async New(env: MSafeEnv, options?: MSafeConfigOptions) {\n const globals = await MSafeGlobals.New(env, options);\n return new MSafeClient(globals);\n }\n\n async connectWallet(input: { wallet: IWallet; jwtToken?: JWTToken }): Promise<JWTToken> {\n if (input.jwtToken) {\n const verified = await this.backend.verifyToken(input.jwtToken);\n if (verified) {\n this.globals.wallet = input.wallet;\n this.backend.setJWTToken(input.jwtToken);\n return input.jwtToken;\n }\n }\n const jwt = await this.authSign(input.wallet);\n this.globals.wallet = input.wallet;\n this.backend.setJWTToken(jwt);\n return jwt;\n }\n\n private async authSign(wallet: IWallet): Promise<JWTToken> {\n const messageStr = SigningMessageHelper.loginMessageWithTimestamp(new Date().toUTCString());\n const sig = await wallet.signPersonalMessage({\n messageStr,\n });\n return this.backend.authSign({\n address: await wallet.address(),\n message: messageStr,\n signature: sig.signature,\n walletType: wallet.walletType,\n });\n }\n\n async userInfo() {\n return this.globals.backend.getUserInfo();\n }\n\n async ownedMSafe(pagination?: IPageOptions): Promise<IPagedResult<IMSafeConfig>> {\n return this.globals.backend.getOwnedMSafeByStatus({ status: UserMSafeStatus.active, pagination });\n }\n\n async createAccount(info: CreateMSafeInfo) {\n return this.creationHelper.submitMSafeCreation(info);\n }\n\n getMSafeAccount(info: IMSafeConfig) {\n return new MSafeAccount(this.globals, info);\n }\n\n async getMSafeAccountFromAddress(msafeAddress: string) {\n const info = await this.backend.getMSafeAccountInfo(msafeAddress);\n return new MSafeAccount(this.globals, info);\n }\n\n // Get the creation helper to calculate the msafe account address,\n // validation, and more.\n get creationHelper() {\n if (!this._creationHelper) {\n this._creationHelper = new CreateHelper(this.globals, this.publicKeyHelper);\n }\n return this._creationHelper;\n }\n\n get publicKeyHelper() {\n if (!this._publicKeyHelper) {\n this._publicKeyHelper = new PublicKeyHelper(this.globals);\n }\n return this._publicKeyHelper;\n }\n\n get config() {\n return this.globals.config;\n }\n\n get backend() {\n return this.globals.backend;\n }\n\n get wallet() {\n return this.globals.wallet;\n }\n\n get AddressBook(): AddressBookSDK {\n return new AddressBookSDK(this.globals);\n }\n\n get Invitation(): InvitationSDK {\n return new InvitationSDK(this.globals);\n }\n\n private async walletAddress() {\n return this.wallet.address();\n }\n}\n","import { IPageOptions, SigningMessageHelper, UpdateAddressBookEntry } from '@msafe/sui3-utils';\n\nimport { MSafeGlobals } from '@/globals';\n\nexport class AddressBookSDK {\n constructor(public readonly globals: MSafeGlobals) {}\n\n async getEntries(pagination?: IPageOptions) {\n return this.globals.backend.getAddressBookEntries(pagination);\n }\n\n async update(updates: UpdateAddressBookEntry[]) {\n const messageStr = SigningMessageHelper.updateAddressBookMessage(updates);\n const sig = await this.globals.wallet.signPersonalMessage({ messageStr });\n return this.globals.backend.updateAddressBook({ updates, signature: sig.signature });\n }\n}\n","import { IMSafeConfig, IPagedResult, IPageOptions, UserMSafeStatus } from '@msafe/sui3-utils';\n\nimport { MSafeGlobals } from '@/globals';\n\nexport class InvitationSDK {\n constructor(public readonly globals: MSafeGlobals) {}\n\n async getMSafeByStatus(status: UserMSafeStatus, pagination?: IPageOptions): Promise<IPagedResult<IMSafeConfig>> {\n return this.globals.backend.getOwnedMSafeByStatus({ status, pagination });\n }\n\n async updateMSafeStatus(msafeAddress: string, status: UserMSafeStatus) {\n return this.globals.backend.updateMSafeStatus({ msafeAddress, status });\n }\n}\n","import {\n CoinTransferIntention,\n IMSafeConfig,\n IProposeIntentionRequest,\n MultiSigAccount,\n ObjectTransferIntention,\n SigningMessageHelper,\n TransactionDefaultApplication,\n TransactionSubTypes,\n TransactionType,\n TxIntention,\n buildObjectTransferTxb,\n buildRejectTxb,\n} from '@msafe/sui3-utils';\nimport { SuiObjectData } from '@mysten/sui.js/client';\nimport { SerializedSignature } from '@mysten/sui.js/cryptography';\nimport { SuiObjectResponse } from '@mysten/sui.js/src/client';\nimport { TransactionBlock } from '@mysten/sui.js/transactions';\nimport { normalizeStructTag } from '@mysten/sui.js/utils';\n\nimport { MSafeGlobals } from '@/globals/MSafeGlobals';\nimport { OwnedCoin } from '@/types/assets';\nimport { Pagination, PendingTx, SimulationResult } from '@/types/msafe';\nimport { CoinHelper } from '@/utils';\nimport { HexToUint8Array } from '@/utils/buffer';\nimport { BatchObjectOptions, getAllOwnedObjects } from '@/utils/iter/object';\n\nexport class MSafeAccount {\n public multiSig: MultiSigAccount;\n\n private coinHelper: CoinHelper;\n\n constructor(\n public readonly globals: MSafeGlobals,\n public readonly info: IMSafeConfig,\n ) {\n this.multiSig = new MultiSigAccount({\n threshold: info.threshold,\n ownersWithWeight: info.owners,\n creationNonce: info.creationNonce,\n });\n this.coinHelper = new CoinHelper(this.suiClient);\n }\n\n static async New(globals: MSafeGlobals, address: string) {\n const info = await globals.backend.getMSafeAccountInfo(address);\n const ms = new MSafeAccount(globals, info);\n if (ms.address !== address) {\n throw new Error('Invalid msafe config with address');\n }\n }\n\n async ownedCoins(): Promise<OwnedCoin[]> {\n const balances = await this.suiClient.getAllBalances({ owner: this.address });\n return Promise.all(\n balances.map(async (balance): Promise<OwnedCoin> => {\n const meta = await this.coinHelper.getCoinMeta(balance.coinType);\n const unlockedBalance = balance.lockedBalance.number\n ? BigInt(balance.totalBalance) - BigInt(balance.lockedBalance.number)\n : BigInt(balance.totalBalance);\n\n return {\n type: normalizeStructTag(balance.coinType),\n balance: BigInt(unlockedBalance),\n metadata: meta,\n };\n }),\n );\n }\n\n async ownedObjects(options?: BatchObjectOptions): Promise<SuiObjectData[]> {\n const filterCoinObjectOptions = {\n filter: (objRes: SuiObjectResponse) => !objRes?.data?.type?.startsWith('0x2::coin::Coin'),\n ...options,\n };\n return getAllOwnedObjects(this.suiClient, this.address, filterCoinObjectOptions);\n }\n\n async pendingTransaction(): Promise<PendingTx | undefined> {\n const res = await this.backend.getPendingTransactions({ msafeAddress: this.address });\n if (!res.pending) {\n return undefined;\n }\n\n const pendingTx = res.pending;\n const rejectPending = res.reject;\n\n return {\n txType: TransactionType.Assets,\n txSubType:\n 'coinType' in pendingTx.intention\n ? TransactionSubTypes.assets.coin.send\n : TransactionSubTypes.assets.object.send,\n createdAt: pendingTx.createdAt as Date,\n creator: pendingTx.creator,\n digest: pendingTx.digest,\n intention: pendingTx.intention,\n sequenceNumber: pendingTx.sequenceNumber,\n payload: pendingTx.payload,\n votes: pendingTx.votes,\n msafeAddress: pendingTx.msafeAddress,\n rejectDigest: rejectPending?.digest ?? '',\n rejectPayload: rejectPending?.payload ?? '',\n rejectVotes: rejectPending?.votes ?? [],\n };\n }\n\n async historyTransaction(pagination?: Pagination) {\n return this.backend.getHistoryTransactions({\n msafeAddress: this.address,\n ...pagination,\n });\n }\n\n async futureIntentions(pagination?: Pagination) {\n return this.backend.getFutureIntentions({ msafeAddress: this.address, ...pagination });\n }\n\n async currentSequenceNumber() {\n return this.backend.getCurrentSequenceNumber(this.address);\n }\n\n async nextSequenceNumber() {\n return this.backend.getNextSequenceNumber(this.address);\n }\n\n async proposeIntention(input: Omit<IProposeIntentionRequest, 'signature' | 'msafeAddress'>) {\n const message = SigningMessageHelper.proposeIntentionMessage({\n msafeAddress: this.address,\n intention: input.intention,\n sn: input.sequenceNumber,\n });\n const signature = await this.wallet.signPersonalMessage({\n messageStr: message,\n });\n\n await this.backend.proposeIntention({\n ...input,\n msafeAddress: this.address,\n signature: signature.signature,\n });\n }\n\n async proposeCoinTransferIntention(intention: CoinTransferIntention) {\n const sn = await this.nextSequenceNumber();\n return this.proposeIntention({\n application: TransactionDefaultApplication,\n txType: TransactionType.Assets,\n txSubType: TransactionSubTypes.assets.coin.send,\n sequenceNumber: sn,\n intention,\n });\n }\n\n async proposeObjectTransferIntention(intention: ObjectTransferIntention) {\n await buildObjectTransferTxb(this.suiClient, intention, this.address);\n const sn = await this.nextSequenceNumber();\n return this.proposeIntention({\n application: TransactionDefaultApplication,\n txType: TransactionType.Assets,\n txSubType: TransactionSubTypes.assets.object.send,\n sequenceNumber: sn,\n intention,\n });\n }\n\n async voteForTransaction(digest: string, payload: string) {\n const payloadBytes = HexToUint8Array(payload);\n const signature = await this.wallet.signTransactionBlock({ transactionBlock: payloadBytes });\n return this.backend.voteForTransaction({\n msafeAddress: this.address,\n digest,\n signature: signature.signature,\n });\n }\n\n // Shortcut for proposing a transaction to be a pending transaction, and add user vote to it.\n // Requires the multi-sig to be empty in pending transaction.\n async proposePendingTransaction(intention: TxIntention) {\n const txb = new TransactionBlock();\n const payload = await txb.build({ client: this.suiClient });\n const digest = await txb.getDigest({ client: this.suiClient });\n const signature = await this.wallet.signTransactionBlock({ transactionBlock: payload });\n return this.backend.proposePendingTransaction({\n msafeAddress: this.address,\n userAddress: await this.userAddress(),\n intention,\n digest,\n signature: signature.signature,\n });\n }\n\n async rejectCurrentTx() {\n const pendingTx = await this.pendingTransaction();\n if (!pendingTx || pendingTx.rejectDigest !== '') {\n throw new Error('Already rejected');\n }\n\n const payloadToReject = pendingTx.payload;\n const rejectTxb = buildRejectTxb(this.address, payloadToReject);\n const digest = await rejectTxb.getDigest({ client: this.suiClient });\n const payload = await rejectTxb.build({ client: this.suiClient });\n const signature = await this.wallet.signTransactionBlock({ transactionBlock: payload });\n return this.backend.rejectCurrentTx({\n msafeAddress: this.address,\n digest,\n signature: signature.signature,\n });\n }\n\n async buildNextIntentionAndAddToPending() {\n return this.backend.buildNextIntentionAndAddToPending({ msafeAddress: this.address });\n }\n\n async skipNextFailedIntention() {\n return this.backend.skipNextFailedIntention({ msafeAddress: this.address });\n }\n\n async simulateIntention(): Promise<SimulationResult> {\n // Todo, move to API\n const txb = new TransactionBlock(); // await buildIntentionTransaction(this.suiClient, intention, this.address);\n txb.setSender(this.address);\n if (!txb.blockData.gasConfig.price) {\n const refGas = await this.suiClient.getReferenceGasPrice();\n txb.setGasPrice(refGas);\n }\n const payload = await txb.build({ client: this.suiClient });\n const dryRunResult = await this.suiClient.dryRunTransactionBlock({ transactionBlock: payload });\n\n const success = dryRunResult.effects.status.status === 'success';\n const errorMsg = dryRunResult.effects.status.error;\n const gasPrice = BigInt(txb.blockData.gasConfig.price as string);\n const { gasUsed } = dryRunResult.effects;\n\n return {\n success,\n errorMsg,\n gasPrice,\n gasUsed,\n dryRunResult,\n };\n }\n\n async executePendingTx(pending: PendingTx) {\n let gotSigs: Map<string, string>;\n let payload: string;\n if (pending.votes.length >= this.info.threshold) {\n gotSigs = new Map(pending.votes.map((vote) => [vote.userAddress, vote.signature]));\n payload = pending.payload;\n } else if (pending.rejectVotes && pending.rejectPayload && pending.rejectVotes?.length >= this.info.threshold) {\n gotSigs = new Map(pending.rejectVotes.map((vote) => [vote.userAddress, vote.signature]));\n payload = pending.rejectPayload;\n } else {\n throw new Error('Not enough signatures');\n }\n\n const sigs: SerializedSignature[] = [];\n for (let i = 0; i < this.info.owners.length; i++) {\n const owner = this.info.owners[i];\n const signature = gotSigs.get(owner.address);\n if (signature) {\n sigs.push(signature);\n }\n }\n const multiSignature = this.multiSig.combinePartialSignatures(sigs);\n return this.suiClient.executeTransactionBlock({\n transactionBlock: HexToUint8Array(payload),\n signature: multiSignature,\n options: { showEffects: true },\n });\n }\n\n get address() {\n return this.multiSig.address;\n }\n\n private get backend() {\n return this.globals.backend;\n }\n\n private get wallet() {\n return this.globals.wallet;\n }\n\n private async userAddress() {\n return this.globals.wallet.address();\n }\n\n private get suiClient() {\n return this.globals.suiClient;\n }\n}\n","export function stringToBuffer(s: string) {\n return Buffer.from(s, 'utf-8');\n}\n\nexport function Uint8ArrayToHex(b: Uint8Array): string {\n return `0x${Array.prototype.map.call(b, (x) => `0${x.toString(16)}`.slice(-2)).join('')}`;\n}\n\nexport function HexToUint8Array(hex: string): Uint8Array {\n return Uint8Array.from(Buffer.from(hex.startsWith('0x') ? hex.slice(2) : hex, 'hex'));\n}\n","import { SerializedSignature } from '@mysten/sui.js/cryptography';\nimport { verifyPersonalMessage, verifyTransactionBlock } from '@mysten/sui.js/verify';\n\nimport { stringToBuffer } from '@/utils/buffer';\nimport { Formatter } from '@/utils/format';\n\nexport class SignatureVerifier {\n static async getPublicKeyFromSignature(input: {\n message: Uint8Array;\n messageType: 'TransactionBlock' | 'Personal';\n signature: SerializedSignature;\n }) {\n if (input.messageType === 'TransactionBlock') {\n return verifyTransactionBlock(input.message, input.signature);\n }\n return verifyPersonalMessage(input.message, input.signature);\n }\n\n static async getPublicKeyFromPersonalSignature(input: { messageStr: string; signature: SerializedSignature }) {\n const message = stringToBuffer(input.messageStr);\n return this.getPublicKeyFromSignature({\n message,\n messageType: 'Personal',\n signature: input.signature,\n });\n }\n\n static async verifySignature(input: {\n message: Uint8Array;\n messageType: 'TransactionBlock' | 'Personal';\n signature: SerializedSignature;\n targetAddress: string;\n }) {\n const publicKey = await SignatureVerifier.getPublicKeyFromSignature(input);\n return Formatter.isSuiAddressEqual(publicKey.toSuiAddress(), input.targetAddress);\n }\n\n static async verifyPersonalSignature(input: {\n messageStr: string;\n signature: SerializedSignature;\n targetAddress: string;\n }) {\n const message = stringToBuffer(input.messageStr);\n return this.verifySignature({\n message,\n messageType: 'Personal',\n signature: input.signature,\n targetAddress: input.targetAddress,\n });\n }\n\n static async verifyTransactionSignature(input: {\n payload: Uint8Array;\n signature: SerializedSignature;\n targetAddress: string;\n }): Promise<boolean> {\n return this.verifySignature({\n messageType: 'TransactionBlock',\n message: input.payload,\n signature: input.signature,\n targetAddress: input.targetAddress,\n });\n }\n}\n","import { normalizeSuiAddress, normalizeStructTag } from '@mysten/sui.js/utils';\n\nimport { Coin } from '@/utils/coin';\n\nexport class Formatter {\n static normalizeSuiAddress(addr: string) {\n return normalizeSuiAddress(addr);\n }\n\n static normalizeStructTag(struct: string) {\n return normalizeStructTag(struct);\n }\n\n static isSuiAddressEqual(addr1: string, addr2: string) {\n return normalizeSuiAddress(addr1) === normalizeSuiAddress(addr2);\n }\n\n static isSuiStructEqual(struct1: string, struct2: string) {\n return normalizeStructTag(struct1) === normalizeStructTag(struct2);\n }\n\n static isCoinObjectType(struct: string) {\n return Coin.isCoin(struct);\n }\n}\n","import { CoinMetadata, SuiClient, SuiObjectData } from '@mysten/sui.js/client';\nimport { normalizeStructTag } from '@mysten/sui.js/utils';\n\n// CoinHelper is the coin helper to query for coin metadata.\nexport class CoinHelper {\n private _client: SuiClient;\n\n private _coinMetaReg: Map<string, CoinMetadata>;\n\n constructor(client: SuiClient) {\n this._client = client;\n this._coinMetaReg = new Map();\n }\n\n async getCoinMeta(coinType: string): Promise<CoinMetadata | undefined> {\n const normalized = normalizeStructTag(coinType);\n if (this._coinMetaReg.has(normalized)) {\n return this._coinMetaReg.get(normalized);\n }\n const meta = await this.queryCoinMeta(normalized);\n if (meta) {\n this._coinMetaReg.set(normalized, meta);\n }\n return meta;\n }\n\n private async queryCoinMeta(coinType: string): Promise<CoinMetadata | undefined> {\n const res = await this._client.getCoinMetadata({ coinType });\n return res || undefined;\n }\n}\n\n// Copied from sui/sdk/typescript/src/framework/framework.ts\n\nexport const COIN_TYPE_ARG_REGEX =\n /^0x0000000000000000000000000000000000000000000000000000000000000002::coin::Coin<(.+)>$/;\n\nexport class Coin {\n static isCoin(type: string | undefined | null): boolean {\n if (!type) {\n return false;\n }\n return normalizeStructTag(type).match(COIN_TYPE_ARG_REGEX) != null;\n }\n\n static getCoinType(type: string) {\n const [, res] = normalizeStructTag(type).match(COIN_TYPE_ARG_REGEX) ?? [];\n return res || null;\n }\n\n static getBalance(data: SuiObjectData): bigint | undefined {\n if (!Coin.isCoin(data.type)) {\n return undefined;\n }\n if (data.content?.dataType !== 'moveObject') {\n return undefined;\n }\n const { balance } = data.content?.fields as any;\n if (balance === undefined) {\n return undefined;\n }\n return BigInt(balance);\n }\n}\n","import { PublicKeySerde } from '@msafe/sui3-utils';\nimport { SuiClient, PaginatedTransactionResponse, PaginatedCoins, CoinStruct } from '@mysten/sui.js/client';\nimport { parseSerializedSignature, PublicKey, SerializedSignature } from '@mysten/sui.js/cryptography';\nimport { MultiSigPublicKey } from '@mysten/sui.js/multisig';\n\nimport { Formatter } from '@/utils/format';\n\nexport const SUI_COIN = '0x2::sui::SUI';\n\nexport async function getPublicKeyFromChain(suiClient: SuiClient, address: string): Promise<PublicKey | undefined> {\n let txs: PaginatedTransactionResponse;\n try {\n txs = await suiClient.queryTransactionBlocks({\n // Disable naming rule since the variable is defined by Mysten\n filter: { FromAddress: address },\n options: { showInput: true },\n limit: 2,\n });\n } catch (e) {\n // Currently when there is no history transaction, will report an error:\n // Error: byte deserialization failed, cause by: Odd number of digits\n // TODO: remove the catch logic when sui part is fixed;\n return undefined;\n }\n\n if (txs.data.length === 0 || !txs.data[0].transaction?.txSignatures) {\n return undefined;\n }\n const tx = txs.data[0];\n const signatures = tx.transaction?.txSignatures as string[];\n\n for (let i = 0; i !== signatures.length; i++) {\n const serializedSig = signatures[i];\n const pk = getAddressFromSignatures(serializedSig, address);\n if (!pk) {\n continue;\n }\n return pk;\n }\n return undefined;\n}\n\nfunction getAddressFromSignatures(serializedSig: SerializedSignature, targetAddress: string) {\n const decoded = parseSerializedSignature(serializedSig);\n switch (decoded.signatureScheme) {\n case 'MultiSig': {\n const multiSigAddress = new MultiSigPublicKey(decoded.multisig.multisig_pk).toSuiAddress();\n if (Formatter.isSuiAddressEqual(multiSigAddress, targetAddress)) {\n throw new Error('multi-sig wallet cannot be owner');\n }\n return undefined;\n }\n case 'ZkLogin': {\n if (Formatter.isSuiAddressEqual(decoded.zkLogin.address, targetAddress)) {\n throw new Error('ZkLogin wallet cannot be owner');\n }\n return undefined;\n }\n\n case 'ED25519':\n case 'Secp256k1':\n case 'Secp256r1': {\n const pk = PublicKeySerde.de({ publicKeyEncoded: decoded.publicKey, schema: decoded.signatureScheme });\n if (Formatter.isSuiAddressEqual(pk.toSuiAddress(), targetAddress)) {\n return pk;\n }\n return undefined;\n }\n\n default:\n throw new Error('Unknown schema');\n }\n}\n\nexport async function getAllCoins(input: { suiClient: SuiClient; owner: string; coinType: string | undefined }) {\n let hasNext = true;\n let cursor: string | undefined | null;\n const res: CoinStruct[] = [];\n while (hasNext) {\n const currentPage: PaginatedCoins = await input.suiClient.getCoins({\n owner: input.owner,\n coinType: input.coinType,\n cursor,\n });\n res.push(...currentPage.data);\n hasNext = currentPage.hasNextPage;\n cursor = currentPage.nextCursor;\n }\n return res;\n}\n","import { PagedData, Requester } from './requester';\n\nexport const REQUEST_PAGE_SIZE = 25;\n\nexport interface SuiIterator<T> {\n next: () => Promise<T | undefined>;\n hasNext: () => Promise<boolean>;\n}\n\nexport async function getAllFromIterator<T>(it: SuiIterator<T>): Promise<(T | undefined) | (T | undefined)[]> {\n const res: (T | undefined)[] = [];\n while (await it.hasNext()) {\n const val = await it.next();\n res.push(val);\n }\n if (res && Array.isArray(res[0])) {\n return res.flat(1) as T;\n }\n return res;\n}\n\nexport class PagedIterator<T> implements SuiIterator<(T | undefined)[]> {\n private curPage: PagedData<T> | undefined;\n\n private init: boolean;\n\n constructor(public readonly requester: Requester<T>) {\n this.curPage = undefined;\n this.init = true;\n }\n\n async hasNext(): Promise<boolean> {\n if (this.init) {\n if (!this.curPage) {\n this.curPage = await this.requester.doNextRequest();\n }\n return !!this.curPage.data?.length || this.curPage.hasNext;\n }\n if (!this.curPage) {\n throw new Error('invalid implementation of iterator');\n }\n return this.curPage.hasNext;\n }\n\n async next(): Promise<(T | undefined)[]> {\n if (this.init) {\n this.init = false;\n if (!this.curPage) {\n this.curPage = await this.requester.doNextRequest();\n }\n return this.curPage.data;\n }\n this.curPage = await this.requester.doNextRequest();\n return this.curPage.data;\n }\n}\n\nexport class EntryIterator<T> implements SuiIterator<T> {\n cursor: number;\n\n pager: PagedIterator<T>;\n\n curData: (T | undefined)[];\n\n constructor(public readonly requester: Requester<T>) {\n this.pager = new PagedIterator<T>(requester);\n this.curData = [];\n this.cursor = 0;\n }\n\n async hasNext(): Promise<boolean> {\n if (this.cursor < this.curData.length - 1) {\n return true;\n }\n return this.pager.hasNext();\n }\n\n async next(): Promise<T | undefined> {\n this.cursor += 1;\n while (this.cursor >= this.curData.length) {\n if (!(await this.pager.hasNext())) {\n throw new Error('not more data'); // Shall not happen for legit data source.\n } else {\n this.curData = await this.pager.next();\n this.cursor = 0;\n }\n }\n return this.curData[this.cursor];\n }\n}\n","import { SuiObjectResponse, SuiObjectDataOptions, SuiObjectData, SuiClient } from '@mysten/sui.js/client';\n\nimport { EntryIterator, getAllFromIterator, REQUEST_PAGE_SIZE, SuiIterator } from './iterator';\nimport { PagedData, Requester } from './requester';\n\n// TODO: setup testnet faucet and test this file\n\nexport type ObjectFilter = (objRes: SuiObjectResponse) => boolean;\n\n// OidIter is the iterator to give the list of object ids\nexport type OidIter = SuiIterator<string>;\n\nexport interface BatchObjectOptions {\n filter?: ObjectFilter;\n pageSize?: number;\n objectOptions?: SuiObjectDataOptions;\n}\n\n// getObjectsById get the list of objects by id.\n// Compared with the multiGetObject method defined by SUI, this method will do the pagination\n// for get object requests.\nexport async function getObjectsById(\n provider: SuiClient,\n ids: string[],\n options?: BatchObjectOptions,\n): Promise<(SuiObjectData | undefined)[]> {\n const oidIter = new ListOidIterator(ids);\n const iter = new ObjectBatchIterator(provider, oidIter, options);\n return (await getAllFromIterator(iter)) as (SuiObjectData | undefined)[];\n}\n\n// ListOidIterator is the iterator that iterate through a list of ids.\n// This iterator shall be used when the number requested objects is big\n// which is inappropriate to fit the requested objects into a single\n// request.\nexport class ListOidIterator implements OidIter {\n cursor: number;\n\n constructor(public readonly ids: string[]) {\n this.cursor = -1;\n }\n\n async hasNext(): Promise<boolean> {\n return this.cursor < this.ids.length - 1;\n }\n\n async next(): Promise<string> {\n this.cursor += 1;\n if (this.cursor >= this.ids.length) {\n throw new Error('invalid iterator implementation'); // Shall be unreachable\n }\n return this.ids[this.cursor];\n }\n}\n\nexport class ObjectBatchIterator extends EntryIterator<SuiObjectData> {\n constructor(\n public readonly provider: SuiClient,\n public readonly idIter: OidIter,\n public readonly options?: BatchObjectOptions,\n ) {\n super(new ObjectBatchRequester(provider, idIter, options));\n }\n}\n\n// TODO: Test with customize objects\nexport class ObjectBatchRequester implements Requester<SuiObjectData> {\n filter: ObjectFilter | undefined;\n\n pageSize: number;\n\n objectOptions: SuiObjectDataOptions;\n\n constructor(\n public readonly provider: SuiClient,\n public readonly stringIter: OidIter,\n public options?: BatchObjectOptions,\n ) {\n this.filter = options?.filter;\n this.pageSize = options?.pageSize || REQUEST_PAGE_SIZE;\n this.objectOptions = options?.objectOptions || {\n showType: true,\n showContent: true,\n };\n }\n\n async doNextRequest(): Promise<PagedData<SuiObjectData>> {\n const requestPage: string[] = [];\n while (requestPage.length < this.pageSize) {\n const hasNext = await this.stringIter.hasNext();\n if (!hasNext) {\n break;\n }\n const objId = await this.stringIter.next();\n if (objId) {\n requestPage.push(objId);\n }\n }\n const res: SuiObjectResponse[] = await this.provider.multiGetObjects({\n ids: requestPage,\n options: this.objectOptions,\n });\n let filtered: SuiObjectResponse[];\n if (this.filter) {\n const { filter } = this;\n filtered = res.filter((r: SuiObjectResponse) => filter?.(r));\n } else {\n filtered = res;\n }\n return {\n data: filtered.map((objRes) => objRes.data).filter((data) => data) as SuiObjectData[],\n hasNext: await this.stringIter.hasNext(),\n };\n }\n}\n\nexport async function getAllOwnedObjects(\n provider: SuiClient,\n owner: string,\n options?: BatchObjectOptions,\n): Promise<SuiObjectData[]> {\n const iter = new OwnedObjectIterator(provider, owner, options);\n return (await getAllFromIterator(iter)) as SuiObjectData[];\n}\n\nexport class OwnedObjectIterator extends EntryIterator<SuiObjectData> implements SuiIterator<SuiObjectData> {\n constructor(\n public readonly provider: SuiClient,\n public readonly owner: string,\n public readonly options?: BatchObjectOptions,\n ) {\n super(new OwnedObjectRequester(provider, owner, options));\n }\n}\n\nexport class OwnedObjectRequester implements Requester<SuiObjectData> {\n nextCursor: string | null;\n\n public filter: ObjectFilter | undefined;\n\n public pageSize: number;\n\n public objectOptions: SuiObjectDataOptions;\n\n constructor(\n public readonly provider: SuiClient,\n public readonly owner: string,\n public readonly options?: BatchObjectOptions,\n ) {\n this.nextCursor = null;\n this.filter = options?.filter;\n this.pageSize = options?.pageSize || REQUEST_PAGE_SIZE;\n this.objectOptions = options?.objectOptions || {\n showType: true,\n showContent: true,\n };\n }\n\n async doNextRequest(): Promise<PagedData<SuiObjectData>> {\n const res = await this.provider.getOwnedObjects({\n owner: this.owner,\n options: this.objectOptions,\n cursor: this.nextCursor,\n limit: this.pageSize,\n });\n this.nextCursor = res.nextCursor as string;\n let filtered: SuiObjectResponse[];\n if (this.filter) {\n const { filter } = this;\n filtered = res.data.filter((obj: SuiObjectResponse) => filter?.(obj));\n } else {\n filtered = res.data;\n }\n return {\n data: filtered.map((r: SuiObjectResponse) => r.data).filter((data) => data) as SuiObjectData[],\n hasNext: res.hasNextPage,\n };\n }\n}\n","import { PublicKey } from '@mysten/sui.js/src/cryptography';\n\nimport { MSafeGlobals } from '@/globals/MSafeGlobals';\nimport { getPublicKeyFromChain } from '@/utils/sui';\n\n/**\n * PublicKeyHelper is the helper to query for public keys from\n * backend and blockchain.\n */\nexport class PublicKeyHelper {\n private knownPublicKeys: Map<string, PublicKey>;\n\n constructor(public readonly globals: MSafeGlobals) {\n this.knownPublicKeys = new Map<string, PublicKey>();\n }\n\n async getPublicKey(address: string) {\n const cached = this.knownPublicKeys.get(address);\n if (cached) {\n return cached;\n }\n const pk = await this._getPublicKey(address);\n if (pk) {\n this.knownPublicKeys.set(address, pk);\n }\n return pk;\n }\n\n async getPublicKeyBatch(addresses: string[]): Promise<(PublicKey | undefined)[]> {\n const results: (PublicKey | undefined)[] = new Array(addresses.length).fill(undefined);\n\n // Query local cache first\n for (let i = 0; i < addresses.length; i++) {\n const address = addresses[i];\n results[i] = this.knownPublicKeys.get(address);\n }\n\n // Query backend in batch\n const emptyIndexes = results\n .map((elem, index) => (elem === undefined ? index : -1))\n .filter((index) => index !== -1);\n if (emptyIndexes.length === 0) {\n return results;\n }\n const backendResult = await this.globals.backend.getPublicKeyBatch(emptyIndexes.map((index) => addresses[index]));\n for (let i = 0; i < emptyIndexes.length; i++) {\n const index = emptyIndexes[i];\n results[index] = backendResult[i];\n }\n\n // Query the public key from blockchain\n for (let i = 0; i < results.length; i++) {\n if (results[i] === undefined) {\n results[i] = await this.getPublicKeyFromChain(addresses[i]);\n }\n }\n\n // Finally, write the public keys to the local cache\n for (let i = 0; i < addresses.length; i++) {\n if (results[i]) {\n this.knownPublicKeys.set(addresses[i], results[i] as PublicKey);\n }\n }\n return results;\n }\n\n private async _getPublicKey(address: string) {\n const pkBackend = await this.getPublicKeyFromBackend(address);\n if (pkBackend) {\n return pkBackend;\n }\n const pkChain = await this.getPublicKeyFromChain(address);\n if (pkChain) {\n return pkChain;\n }\n return undefined;\n }\n\n private async getPublicKeyFromBackend(address: string): Promise<PublicKey | undefined> {\n try {\n const pk = await this.globals.backend.getPublicKey(address);\n return pk;\n } catch (_) {\n return undefined;\n }\n }\n\n private async getPublicKeyFromChain(address: string): Promise<PublicKey | undefined> {\n return getPublicKeyFromChain(this.globals.suiClient, address);\n }\n}\n","import { SuiClient } from '@mysten/sui.js/client';\n\nimport { BackendImpl } from '@/backend/BackendImpl';\nimport { IBackend } from '@/backend/interface';\nimport { getMSafeConfig, MSafeConfig, MSafeConfigOptions, MSafeEnv } from '@/globals/const';\nimport { IWallet } from '@/types/wallet';\n\nexport class MSafeGlobals {\n public readonly backend: IBackend;\n\n public readonly suiClient: SuiClient;\n\n public readonly config: MSafeConfig;\n\n _wallet: IWallet | undefined;\n\n constructor(input: { backend: IBackend; suiClient: SuiClient; config: MSafeConfig }) {\n this.backend = input.backend;\n this.suiClient = input.suiClient;\n this.config = input.config;\n }\n\n static async New(env: MSafeEnv, options?: MSafeConfigOptions) {\n const config = getMSafeConfig(env, options);\n const suiClient = new SuiClient(config.suiClient);\n const backend = new BackendImpl(config.backend.url);\n return new MSafeGlobals({\n backend,\n suiClient,\n config,\n });\n }\n\n connectWallet(wallet: IWallet) {\n this._wallet = wallet;\n }\n\n get wallet() {\n if (!this._wallet) {\n throw new Error('wallet not connected');\n }\n return this._wallet;\n }\n\n set wallet(val: IWallet) {\n this._wallet = val;\n }\n}\n","import {\n GetHistoryTransactionsResponse,\n GetPendingTransactionResponse,\n GetTransactionIntentionsResponse,\n IAuthLoginReq,\n IAuthLoginResp,\n IBuildTransactionRequest,\n ICreateMSafeReq,\n IGetAddressBookResult,\n IGetHistoryTransactionsRequest,\n IGetIntentionsRequest,\n IGetMSafeQuery,\n IGetMSafesQuery,\n IGetPendingTransactionRequest,\n IGetPublicKeyBatchQuery,\n IGetPublicKeyBatchResp,\n IMSafeConfig,\n IMSafeInfoResp,\n IPageOptions,\n IPagedResult,\n IProposeIntentionRequest,\n ISkipIntentionRequest,\n IUpdateMSafeStatusReq,\n IUserInfoResp,\n IVoteTransactionRequest,\n JWTToken,\n PublicKeySerde,\n TxIntention,\n UpdateAddressBookEntry,\n UserMSafeStatus,\n} from '@msafe/sui3-utils';\nimport { SerializedSignature } from '@mysten/sui.js/cryptography';\nimport { PublicKey } from '@mysten/sui.js/src/cryptography';\nimport axios from 'axios';\n\nimport { IBackend } from '@/backend/interface';\n\nexport class BackendImpl implements IBackend {\n private _token: JWTToken;\n\n constructor(private readonly apiURL: string) {}\n\n async authSign(input: IAuthLoginReq): Promise<JWTToken> {\n const res = await axios.post<IAuthLoginResp>(`${this.apiURL}/auth/login`, input);\n // TODO unify response struct\n if (res.status !== 200 && res.status !== 201) {\n throw new Error(`invalid authSign return: ${res}`);\n }\n this._token = res.data.accessToken;\n return this._token;\n }\n\n async verifyToken(jwt: JWTToken): Promise<boolean> {\n try {\n const res = await axios.get(`${this.apiURL}/auth`, { headers: this.headers(jwt) });\n return res.status === 200;\n } catch (_) {\n return false;\n }\n }\n\n setJWTToken(token: JWTToken) {\n this._token = token;\n }\n\n async getPublicKey(address: string): Promise<PublicKey | undefined> {\n return (await this.getPublicKeyBatch([address]))[0];\n }\n\n async getPublicKeyBatch(addresses: string[]): Promise<(PublicKey | undefined)[]> {\n const query: IGetPublicKeyBatchQuery = {\n userAddressList: addresses,\n };\n const res = await axios.get<IGetPublicKeyBatchResp>(`${this.apiURL}/user/public-keys`, {\n params: query,\n headers: this.headers(),\n });\n\n // TODO unify response struct\n if (res.status !== 200 && res.status !== 201) {\n throw new Error(`invalid getPublicKeyBatch return: ${res}`);\n }\n return res.data?.map((publicKeyWithSchema) =>\n publicKeyWithSchema ? PublicKeySerde.de(publicKeyWithSchema) : undefined,\n );\n }\n\n async getMSafeAccountInfo(msafeAddress: string): Promise<IMSafeConfig> {\n const q: IGetMSafeQuery = {\n msafeAddress,\n };\n const res = await axios.get<IMSafeInfoResp>(`${this.apiURL}/msafe`, {\n params: q,\n headers: this.headers(),\n });\n // TODO unify response struct\n if (res.status !== 200 && res.status !== 201) {\n throw new Error(`invalid getPublicKeyBatch return: ${res}`);\n }\n return BackendImpl.toMSafeConfig(res.data);\n }\n\n async getUserInfo(): Promise<IUserInfoResp> {\n const userRes = await axios.get<IUserInfoResp>(`${this.apiURL}/user`, {\n headers: this.headers(),\n });\n // TODO unify response struct\n if (userRes.status !== 200 && userRes.status !== 201) {\n throw new Error(`invalid getPublicKeyBatch return: ${userRes}`);\n }\n return userRes.data;\n }\n\n async getOwnedMSafeByStatus(input: {\n status?: UserMSafeStatus;\n pagination?: IPageOptions;\n }): Promise<IPagedResult<IMSafeConfig>> {\n const q: IGetMSafesQuery = {\n status: input.status ?? UserMSafeStatus.active,\n ...(input.pagination\n ? {\n page: input.pagination.page.toString(),\n limit: input.pagination.limit.toString(),\n }\n : {}),\n };\n const res = await axios.get<IPagedResult<IMSafeInfoResp>>(`${this.apiURL}/msafe/owned`, {\n params: q,\n headers: this.headers(),\n });\n if (res.status !== 200 && res.status !== 201) {\n throw new Error(`invalid getOwnedMSafeByStatus return: ${res}`);\n }\n return {\n data: res.data.data.map(BackendImpl.toMSafeConfig),\n meta: res.data.meta,\n };\n }\n\n async updateMSafeStatus(input: { msafeAddress: string; status: UserMSafeStatus }): Promise<void> {\n const p: IUpdateMSafeStatusReq = input;\n const res = await axios.post(`${this.apiURL}/msafe/status`, p, { headers: this.headers() });\n if (res.status !== 200 && res.status !== 201) {\n throw new Error(`Invalid updateMSafeStatus return: ${res}`);\n }\n }\n\n async getPendingTransactions(input: IGetPendingTransactionRequest): Promise<GetPendingTransactionResponse> {\n const res = await axios.get<GetPendingTransactionResponse>(`${this.apiURL}/transaction/pending`, {\n params: input,\n headers: this.headers(),\n });\n if (res.status !== 200 && res.status !== 201) {\n throw new Error(`invalid getPublicKeyBatch return: ${res}`);\n }\n return res.data;\n }\n\n async getHistoryTransactions(input: IGetHistoryTransactionsRequest): Promise<GetHistoryTransactionsResponse> {\n const res = await axios.get<GetHistoryTransactionsResponse>(`${this.apiURL}/transaction/history`, {\n params: input,\n headers: this.headers(),\n });\n if (res.status !== 200 && res.status !== 201) {\n throw new Error(`invalid getCurrentSequenceNumber return: ${res}`);\n }\n return res.data;\n }\n\n async getFutureIntentions(input: IGetIntentionsRequest): Promise<GetTransactionIntentionsResponse> {\n const res = await axios.get<GetTransactionIntentionsResponse>(`${this.apiURL}/transaction/intention`, {\n params: input,\n headers: this.headers(),\n });\n if (res.status !== 200 && res.status !== 201) {\n throw new Error(`invalid getCurrentSequenceNumber return: ${res}`);\n }\n return res.data;\n }\n\n async getCurrentSequenceNumber(address: string): Promise<number> {\n const res = await axios.get<number>(`${this.apiURL}/transaction/sn/current`, {\n params: {\n msafeAddress: address,\n },\n headers: this.headers(),\n });\n if (res.status !== 200 && res.status !== 201) {\n throw new Error(`invalid getCurrentSequenceNumber return: ${res}`);\n }\n return res.data;\n }\n\n async getNextSequenceNumber(address: string): Promise<number> {\n const res = await axios.get<number>(`${this.apiURL}/transaction/sn/next`, {\n params: {\n msafeAddress: address,\n },\n headers: this.headers(),\n });\n if (res.status !== 200 && res.status !== 201) {\n throw new Error(`invalid getNextSequenceNumber return: ${res}`);\n }\n return res.data;\n }\n\n async createMSafeAccount(input: ICreateMSafeReq): Promise<void> {\n const res = await axios.post(`${this.apiURL}/msafe/create`, input, {\n headers: this.headers(),\n });\n if (res.status !== 200 && res.status !== 201) {\n throw new Error(`invalid createMSafeAccount return: ${res}`);\n }\n }\n\n async proposeIntention(input: IProposeIntentionRequest): Promise<void> {\n const res = await axios.post(`${this.apiURL}/transaction/intention`, input, { headers: this.headers() });\n if (res.status !== 200 && res.status !== 201) {\n throw new Error(`invalid proposeIntention return: ${res}`);\n }\n }\n\n // TODO later\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n async proposePendingTransaction(_input: {\n intention: TxIntention;\n userAddress: string;\n msafeAddress: string;\n digest: string;\n signature: SerializedSignature;\n }): Promise<void> {\n return undefined;\n }\n\n async rejectCurrentTx(input: IVoteTransactionRequest) {\n const res = await axios.post(`${this.apiURL}/transaction/pending/reject`, input, {\n headers: this.headers(),\n });\n if (res.status !== 200 && res.status !== 201) {\n throw new Error(`invalid voteForTransaction return: ${res}`);\n }\n }\n\n async voteForTransaction(input: IVoteTransactionRequest) {\n const res = await axios.post(`${this.apiURL}/transaction/pending/vote`, input, {\n headers: this.headers(),\n });\n if (res.status !== 200 && res.status !== 201) {\n throw new Error(`invalid voteForTransaction return: ${res}`);\n }\n }\n\n async buildNextIntentionAndAddToPending(input: IBuildTransactionRequest) {\n const res = await axios.post(`${this.apiURL}/transaction/pending/build`, input, { headers: this.headers() });\n if (res.status !== 200 && res.status !== 201) {\n throw new Error(`invalid buildNextIntentionAndAddToPending return: ${res}`);\n }\n }\n\n async skipNextFailedIntention(input: ISkipIntentionRequest) {\n const res = await axios.post(`${this.apiURL}/transaction/pending/skip`, input, { headers: this.headers() });\n if (res.status !== 200 && res.status !== 201) {\n throw new Error(`invalid skipNextFailedIntention return: ${res}`);\n }\n }\n\n async getAddressBookEntries(pagination?: IPageOptions): Promise<IGetAddressBookResult> {\n const res = await axios.get<IGetAddressBookResult>(`${this.apiURL}/address-book`, {\n headers: this.headers(),\n params: pagination,\n });\n if (res.status !== 200) {\n throw new Error(`Invalid address-book return: ${res}`);\n }\n return res.data;\n }\n\n async updateAddressBook(input: { updates: UpdateAddressBookEntry[]; signature: SerializedSignature }) {\n const res = await axios.post(`${this.apiURL}/address-book`, input, { headers: this.headers() });\n if (res.status !== 200 && res.status !== 201) {\n throw new Error(`invalid updateAddressBook return: ${res}`);\n }\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n async processExecutedTransaction(_digest: string) {\n return undefined;\n }\n\n private headers(token?: string) {\n return { Authorization: `Bearer ${token || this._token}` };\n }\n\n private static toMSafeConfig(resp: IMSafeInfoResp): IMSafeConfig {\n return {\n ...resp,\n owners: resp.owners.map((owner) => ({\n address: owner.address,\n weight: owner.weight,\n publicKey: PublicKeySerde.de({\n publicKeyEncoded: owner.publicKeyEncoded,\n schema: owner.schema,\n }),\n })),\n };\n }\n}\n","export enum MSafeEnv {\n local = 'local',\n unit = 'unit',\n dev = 'dev',\n prev = 'prev',\n prod = 'prod',\n}\n\nexport interface MSafeConfig {\n suiClient: {\n url: string;\n };\n backend: {\n url: string;\n };\n syncingURL: string;\n}\n\nexport interface MSafeConfigOptions {\n suiClient?: {\n url?: string;\n };\n backend?: {\n url?: string;\n };\n}\nexport const MSAFE_APPLICATION = 'msafe';\n\nexport const TESTNET_RPC_URL = 'https://sui-testnet.blockvision.org/v1/2Sgk89ivT64MnKdcGzjmyjY2ndD';\nexport const MAINNET_RPC_URL = 'https://sui-mainnet.blockvision.org/v1/2Sgk7NPvqkd7mESYkxF01yX15l7';\n\nexport const LOCAL_API_URL = 'http://127.0.0.1:3000';\nexport const LOCAL_SYNCING_URL = 'http://127.0.0.1:3001';\n\nexport const DEV_API_URL = 'http://13.56.226.148';\nexport const DEV_SYNCING_URL = 'http://52.53.228.20';\n\nexport const ENV_CONFIGS = new Map<MSafeEnv, MSafeConfig>([\n [\n MSafeEnv.unit,\n {\n suiClient: {\n url: TESTNET_RPC_URL,\n },\n backend: {\n url: LOCAL_API_URL,\n },\n syncingURL: LOCAL_SYNCING_URL,\n },\n ],\n [\n MSafeEnv.local,\n {\n suiClient: {\n url: TESTNET_RPC_URL,\n },\n backend: {\n url: LOCAL_API_URL,\n },\n syncingURL: LOCAL_SYNCING_URL,\n },\n ],\n [\n MSafeEnv.dev,\n {\n suiClient: {\n url: TESTNET_RPC_URL,\n },\n backend: {\n url: DEV_API_URL,\n },\n syncingURL: DEV_SYNCING_URL,\n },\n ],\n]);\n\nexport function getMSafeConfig(env: MSafeEnv, options?: MSafeConfigOptions) {\n const config = ENV_CONFIGS.get(env);\n if (!config) {\n throw new Error('Unknown environment');\n }\n if (options?.suiClient?.url) {\n config.suiClient.url = options.suiClient.url;\n }\n if (options?.backend?.url) {\n config.backend.url = options.backend.url;\n }\n return config;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,wBAAsF;AAO/E,IAAM,eAAN,MAAmB;AAAA,EACxB,YACkB,SACA,UAChB;AAFgB;AACA;AAAA,EACf;AAAA,EAEH,MAAM,kBAAkB,WAAqB;AAC3C,WAAO,KAAK,SAAS,kBAAkB,SAAS;AAAA,EAClD;AAAA,EAEA,MAAM,sBAAsB,MAAuB;AACjD,UAAM,WAAW,MAAM,KAAK,8BAA8B,IAAI;AAC9D,UAAM,KAAK,IAAI,kCAAgB,QAAQ;AACvC,WAAO,GAAG;AAAA,EACZ;AAAA;AAAA,EAGA,MAAM,mBAAmB,YAA6B;AAEpD,WAAO,KAAK,sBAAsB,UAAU;AAAA,EAC9C;AAAA,EAEA,MAAM,oBAAoB,cAA+B;AACvD,UAAM,eAAe,MAAM,KAAK,mBAAmB,YAAY;AAE/D,UAAM,iBAAiB,uCAAqB,mBAAmB,YAAY;AAC3E,UAAM,YAAY,MAAM,KAAK,QAAQ,OAAO,oBAAoB,EAAE,YAAY,eAAe,CAAC;AAE9F,UAAM,KAAK,gBAAgB,cAAc,UAAU,SAAS;AAC5D,WAAO;AAAA,EACT;AAAA,EAEA,MAAc,8BAA8B,MAAgD;AAC1F,UAAM,aAAa,MAAM,KAAK,kBAAkB,KAAK,OAAO,IAAI,CAAC,UAAU,MAAM,OAAO,CAAC;AACzF,eAAW,QAAQ,CAAC,IAAI,MAAM;AAC5B,UAAI,OAAO,QAAW;AACpB,cAAM,IAAI,MAAM,mCAAmC,KAAK,OAAO,CAAC,EAAE,OAAO,EAAE;AAAA,MAC7E;AAAA,IACF,CAAC;AACD,WAAO;AAAA,MACL,WAAW,KAAK;AAAA,MAChB,kBAAkB,KAAK,OAAO,IAAI,CAAC,OAAO,OAAO;AAAA,QAC/C,WAAW,WAAW,CAAC;AAAA,QACvB,QAAQ,MAAM;AAAA,MAChB,EAAE;AAAA,MACF,eAAe,KAAK;AAAA,IACtB;AAAA,EACF;AAAA,EAEA,MAAc,gBAAgB,YAA6B,WAAgC;AACzF,UAAM,MAAM,MAAM,KAAK,SAAS,kBAAkB,WAAW,OAAO,IAAI,CAAC,UAAU,MAAM,OAAO,CAAC;AACjG,UAAM,KAAK,QAAQ,QAAQ,mBAAmB;AAAA,MAC5C,QAAQ,WAAW,OAAO,IAAI,CAAC,OAAO,OAAO;AAAA,QAC3C,SAAS,MAAM;AAAA,QACf,QAAQ,MAAM;AAAA,QACd,GAAG,iCAAe,IAAI,IAAI,CAAC,CAAc;AAAA,MAC3C,EAAE;AAAA,MACF,WAAW,WAAW;AAAA,MACtB,MAAM,WAAW;AAAA;AAAA,MACjB,aAAa,WAAW;AAAA;AAAA,MACxB,eAAe,WAAW;AAAA,MAC1B;AAAA,IACF,CAAC;AAAA,EACH;AACF;;;ACvEA,IAAAA,qBAOO;;;ACPP,IAAAC,qBAA2E;AAIpE,IAAM,iBAAN,MAAqB;AAAA,EAC1B,YAA4B,SAAuB;AAAvB;AAAA,EAAwB;AAAA,EAEpD,MAAM,WAAW,YAA2B;AAC1C,WAAO,KAAK,QAAQ,QAAQ,sBAAsB,UAAU;AAAA,EAC9D;AAAA,EAEA,MAAM,OAAO,SAAmC;AAC9C,UAAM,aAAa,wCAAqB,yBAAyB,OAAO;AACxE,UAAM,MAAM,MAAM,KAAK,QAAQ,OAAO,oBAAoB,EAAE,WAAW,CAAC;AACxE,WAAO,KAAK,QAAQ,QAAQ,kBAAkB,EAAE,SAAS,WAAW,IAAI,UAAU,CAAC;AAAA,EACrF;AACF;;;ACZO,IAAM,gBAAN,MAAoB;AAAA,EACzB,YAA4B,SAAuB;AAAvB;AAAA,EAAwB;AAAA,EAEpD,MAAM,iBAAiB,QAAyB,YAAgE;AAC9G,WAAO,KAAK,QAAQ,QAAQ,sBAAsB,EAAE,QAAQ,WAAW,CAAC;AAAA,EAC1E;AAAA,EAEA,MAAM,kBAAkB,cAAsB,QAAyB;AACrE,WAAO,KAAK,QAAQ,QAAQ,kBAAkB,EAAE,cAAc,OAAO,CAAC;AAAA,EACxE;AACF;;;ACdA,IAAAC,qBAaO;AAIP,0BAAiC;AACjC,IAAAC,gBAAmC;;;AClB5B,SAAS,eAAe,GAAW;AACxC,SAAO,OAAO,KAAK,GAAG,OAAO;AAC/B;AAEO,SAAS,gBAAgB,GAAuB;AACrD,SAAO,KAAK,MAAM,UAAU,IAAI,KAAK,GAAG,CAAC,MAAM,IAAI,EAAE,SAAS,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC;AACzF;AAEO,SAAS,gBAAgB,KAAyB;AACvD,SAAO,WAAW,KAAK,OAAO,KAAK,IAAI,WAAW,IAAI,IAAI,IAAI,MAAM,CAAC,IAAI,KAAK,KAAK,CAAC;AACtF;;;ACTA,oBAA8D;;;ACD9D,IAAAC,gBAAwD;;;ACCxD,mBAAmC;AAG5B,IAAM,aAAN,MAAiB;AAAA,EACd;AAAA,EAEA;AAAA,EAER,YAAY,QAAmB;AAC7B,SAAK,UAAU;AACf,SAAK,eAAe,oBAAI,IAAI;AAAA,EAC9B;AAAA,EAEA,MAAM,YAAY,UAAqD;AACrE,UAAM,iBAAa,iCAAmB,QAAQ;AAC9C,QAAI,KAAK,aAAa,IAAI,UAAU,GAAG;AACrC,aAAO,KAAK,aAAa,IAAI,UAAU;AAAA,IACzC;AACA,UAAM,OAAO,MAAM,KAAK,cAAc,UAAU;AAChD,QAAI,MAAM;AACR,WAAK,aAAa,IAAI,YAAY,IAAI;AAAA,IACxC;AACA,WAAO;AAAA,EACT;AAAA,EAEA,MAAc,cAAc,UAAqD;AAC/E,UAAM,MAAM,MAAM,KAAK,QAAQ,gBAAgB,EAAE,SAAS,CAAC;AAC3D,WAAO,OAAO;AAAA,EAChB;AACF;AAIO,IAAM,sBACX;AAEK,IAAM,OAAN,MAAM,MAAK;AAAA,EAChB,OAAO,OAAO,MAA0C;AACtD,QAAI,CAAC,MAAM;AACT,aAAO;AAAA,IACT;AACA,eAAO,iCAAmB,IAAI,EAAE,MAAM,mBAAmB,KAAK;AAAA,EAChE;AAAA,EAEA,OAAO,YAAY,MAAc;AAC/B,UAAM,CAAC,EAAE,GAAG,QAAI,iCAAmB,IAAI,EAAE,MAAM,mBAAmB,KAAK,CAAC;AACxE,WAAO,OAAO;AAAA,EAChB;AAAA,EAEA,OAAO,WAAW,MAAyC;AACzD,QAAI,CAAC,MAAK,OAAO,KAAK,IAAI,GAAG;AAC3B,aAAO;AAAA,IACT;AACA,QAAI,KAAK,SAAS,aAAa,cAAc;AAC3C,aAAO;AAAA,IACT;AACA,UAAM,EAAE,QAAQ,IAAI,KAAK,SAAS;AAClC,QAAI,YAAY,QAAW;AACzB,aAAO;AAAA,IACT;AACA,WAAO,OAAO,OAAO;AAAA,EACvB;AACF;;;AD3DO,IAAM,YAAN,MAAgB;AAAA,EACrB,OAAO,oBAAoB,MAAc;AACvC,eAAO,mCAAoB,IAAI;AAAA,EACjC;AAAA,EAEA,OAAO,mBAAmB,QAAgB;AACxC,eAAO,kCAAmB,MAAM;AAAA,EAClC;AAAA,EAEA,OAAO,kBAAkB,OAAe,OAAe;AACrD,eAAO,mCAAoB,KAAK,UAAM,mCAAoB,KAAK;AAAA,EACjE;AAAA,EAEA,OAAO,iBAAiB,SAAiB,SAAiB;AACxD,eAAO,kCAAmB,OAAO,UAAM,kCAAmB,OAAO;AAAA,EACnE;AAAA,EAEA,OAAO,iBAAiB,QAAgB;AACtC,WAAO,KAAK,OAAO,MAAM;AAAA,EAC3B;AACF;;;ADlBO,IAAM,oBAAN,MAAM,mBAAkB;AAAA,EAC7B,aAAa,0BAA0B,OAIpC;AACD,QAAI,MAAM,gBAAgB,oBAAoB;AAC5C,iBAAO,sCAAuB,MAAM,SAAS,MAAM,SAAS;AAAA,IAC9D;AACA,eAAO,qCAAsB,MAAM,SAAS,MAAM,SAAS;AAAA,EAC7D;AAAA,EAEA,aAAa,kCAAkC,OAA+D;AAC5G,UAAM,UAAU,eAAe,MAAM,UAAU;AAC/C,WAAO,KAAK,0BAA0B;AAAA,MACpC;AAAA,MACA,aAAa;AAAA,MACb,WAAW,MAAM;AAAA,IACnB,CAAC;AAAA,EACH;AAAA,EAEA,aAAa,gBAAgB,OAK1B;AACD,UAAM,YAAY,MAAM,mBAAkB,0BAA0B,KAAK;AACzE,WAAO,UAAU,kBAAkB,UAAU,aAAa,GAAG,MAAM,aAAa;AAAA,EAClF;AAAA,EAEA,aAAa,wBAAwB,OAIlC;AACD,UAAM,UAAU,eAAe,MAAM,UAAU;AAC/C,WAAO,KAAK,gBAAgB;AAAA,MAC1B;AAAA,MACA,aAAa;AAAA,MACb,WAAW,MAAM;AAAA,MACjB,eAAe,MAAM;AAAA,IACvB,CAAC;AAAA,EACH;AAAA,EAEA,aAAa,2BAA2B,OAInB;AACnB,WAAO,KAAK,gBAAgB;AAAA,MAC1B,aAAa;AAAA,MACb,SAAS,MAAM;AAAA,MACf,WAAW,MAAM;AAAA,MACjB,eAAe,MAAM;AAAA,IACvB,CAAC;AAAA,EACH;AACF;;;AG/DA,IAAAC,qBAA+B;AAE/B,0BAAyE;AACzE,sBAAkC;AAI3B,IAAM,WAAW;AAExB,eAAsB,sBAAsB,WAAsB,SAAiD;AACjH,MAAI;AACJ,MAAI;AACF,UAAM,MAAM,UAAU,uBAAuB;AAAA;AAAA,MAE3C,QAAQ,EAAE,aAAa,QAAQ;AAAA,MAC/B,SAAS,EAAE,WAAW,KAAK;AAAA,MAC3B,OAAO;AAAA,IACT,CAAC;AAAA,EACH,SAAS,GAAG;AAIV,WAAO;AAAA,EACT;AAEA,MAAI,IAAI,KAAK,WAAW,KAAK,CAAC,IAAI,KAAK,CAAC,EAAE,aAAa,cAAc;AACnE,WAAO;AAAA,EACT;AACA,QAAM,KAAK,IAAI,KAAK,CAAC;AACrB,QAAM,aAAa,GAAG,aAAa;AAEnC,WAAS,IAAI,GAAG,MAAM,WAAW,QAAQ,KAAK;AAC5C,UAAM,gBAAgB,WAAW,CAAC;AAClC,UAAM,KAAK,yBAAyB,eAAe,OAAO;AAC1D,QAAI,CAAC,IAAI;AACP;AAAA,IACF;AACA,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAEA,SAAS,yBAAyB,eAAoC,eAAuB;AAC3F,QAAM,cAAU,8CAAyB,aAAa;AACtD,UAAQ,QAAQ,iBAAiB;AAAA,IAC/B,KAAK,YAAY;AACf,YAAM,kBAAkB,IAAI,kCAAkB,QAAQ,SAAS,WAAW,EAAE,aAAa;AACzF,UAAI,UAAU,kBAAkB,iBAAiB,aAAa,GAAG;AAC/D,cAAM,IAAI,MAAM,kCAAkC;AAAA,MACpD;AACA,aAAO;AAAA,IACT;AAAA,IACA,KAAK,WAAW;AACd,UAAI,UAAU,kBAAkB,QAAQ,QAAQ,SAAS,aAAa,GAAG;AACvE,cAAM,IAAI,MAAM,gCAAgC;AAAA,MAClD;AACA,aAAO;AAAA,IACT;AAAA,IAEA,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK,aAAa;AAChB,YAAM,KAAK,kCAAe,GAAG,EAAE,kBAAkB,QAAQ,WAAW,QAAQ,QAAQ,gBAAgB,CAAC;AACrG,UAAI,UAAU,kBAAkB,GAAG,aAAa,GAAG,aAAa,GAAG;AACjE,eAAO;AAAA,MACT;AACA,aAAO;AAAA,IACT;AAAA,IAEA;AACE,YAAM,IAAI,MAAM,gBAAgB;AAAA,EACpC;AACF;AAEA,eAAsB,YAAY,OAA8E;AAC9G,MAAI,UAAU;AACd,MAAI;AACJ,QAAM,MAAoB,CAAC;AAC3B,SAAO,SAAS;AACd,UAAM,cAA8B,MAAM,MAAM,UAAU,SAAS;AAAA,MACjE,OAAO,MAAM;AAAA,MACb,UAAU,MAAM;AAAA,MAChB;AAAA,IACF,CAAC;AACD,QAAI,KAAK,GAAG,YAAY,IAAI;AAC5B,cAAU,YAAY;AACtB,aAAS,YAAY;AAAA,EACvB;AACA,SAAO;AACT;;;ACvFO,IAAM,oBAAoB;AAOjC,eAAsB,mBAAsB,IAAkE;AAC5G,QAAM,MAAyB,CAAC;AAChC,SAAO,MAAM,GAAG,QAAQ,GAAG;AACzB,UAAM,MAAM,MAAM,GAAG,KAAK;AAC1B,QAAI,KAAK,GAAG;AAAA,EACd;AACA,MAAI,OAAO,MAAM,QAAQ,IAAI,CAAC,CAAC,GAAG;AAChC,WAAO,IAAI,KAAK,CAAC;AAAA,EACnB;AACA,SAAO;AACT;AAEO,IAAM,gBAAN,MAAiE;AAAA,EAKtE,YAA4B,WAAyB;AAAzB;AAC1B,SAAK,UAAU;AACf,SAAK,OAAO;AAAA,EACd;AAAA,EAPQ;AAAA,EAEA;AAAA,EAOR,MAAM,UAA4B;AAChC,QAAI,KAAK,MAAM;AACb,UAAI,CAAC,KAAK,SAAS;AACjB,aAAK,UAAU,MAAM,KAAK,UAAU,cAAc;AAAA,MACpD;AACA,aAAO,CAAC,CAAC,KAAK,QAAQ,MAAM,UAAU,KAAK,QAAQ;AAAA,IACrD;AACA,QAAI,CAAC,KAAK,SAAS;AACjB,YAAM,IAAI,MAAM,oCAAoC;AAAA,IACtD;AACA,WAAO,KAAK,QAAQ;AAAA,EACtB;AAAA,EAEA,MAAM,OAAmC;AACvC,QAAI,KAAK,MAAM;AACb,WAAK,OAAO;AACZ,UAAI,CAAC,KAAK,SAAS;AACjB,aAAK,UAAU,MAAM,KAAK,UAAU,cAAc;AAAA,MACpD;AACA,aAAO,KAAK,QAAQ;AAAA,IACtB;AACA,SAAK,UAAU,MAAM,KAAK,UAAU,cAAc;AAClD,WAAO,KAAK,QAAQ;AAAA,EACtB;AACF;AAEO,IAAM,gBAAN,MAAiD;AAAA,EAOtD,YAA4B,WAAyB;AAAzB;AAC1B,SAAK,QAAQ,IAAI,cAAiB,SAAS;AAC3C,SAAK,UAAU,CAAC;AAChB,SAAK,SAAS;AAAA,EAChB;AAAA,EAVA;AAAA,EAEA;AAAA,EAEA;AAAA,EAQA,MAAM,UAA4B;AAChC,QAAI,KAAK,SAAS,KAAK,QAAQ,SAAS,GAAG;AACzC,aAAO;AAAA,IACT;AACA,WAAO,KAAK,MAAM,QAAQ;AAAA,EAC5B;AAAA,EAEA,MAAM,OAA+B;AACnC,SAAK,UAAU;AACf,WAAO,KAAK,UAAU,KAAK,QAAQ,QAAQ;AACzC,UAAI,CAAE,MAAM,KAAK,MAAM,QAAQ,GAAI;AACjC,cAAM,IAAI,MAAM,eAAe;AAAA,MACjC,OAAO;AACL,aAAK,UAAU,MAAM,KAAK,MAAM,KAAK;AACrC,aAAK,SAAS;AAAA,MAChB;AAAA,IACF;AACA,WAAO,KAAK,QAAQ,KAAK,MAAM;AAAA,EACjC;AACF;;;AC2BA,eAAsB,mBACpB,UACA,OACA,SAC0B;AAC1B,QAAM,OAAO,IAAI,oBAAoB,UAAU,OAAO,OAAO;AAC7D,SAAQ,MAAM,mBAAmB,IAAI;AACvC;AAEO,IAAM,sBAAN,cAAkC,cAAmE;AAAA,EAC1G,YACkB,UACA,OACA,SAChB;AACA,UAAM,IAAI,qBAAqB,UAAU,OAAO,OAAO,CAAC;AAJxC;AACA;AACA;AAAA,EAGlB;AACF;AAEO,IAAM,uBAAN,MAA+D;AAAA,EASpE,YACkB,UACA,OACA,SAChB;AAHgB;AACA;AACA;AAEhB,SAAK,aAAa;AAClB,SAAK,SAAS,SAAS;AACvB,SAAK,WAAW,SAAS,YAAY;AACrC,SAAK,gBAAgB,SAAS,iBAAiB;AAAA,MAC7C,UAAU;AAAA,MACV,aAAa;AAAA,IACf;AAAA,EACF;AAAA,EApBA;AAAA,EAEO;AAAA,EAEA;AAAA,EAEA;AAAA,EAgBP,MAAM,gBAAmD;AACvD,UAAM,MAAM,MAAM,KAAK,SAAS,gBAAgB;AAAA,MAC9C,OAAO,KAAK;AAAA,MACZ,SAAS,KAAK;AAAA,MACd,QAAQ,KAAK;AAAA,MACb,OAAO,KAAK;AAAA,IACd,CAAC;AACD,SAAK,aAAa,IAAI;AACtB,QAAI;AACJ,QAAI,KAAK,QAAQ;AACf,YAAM,EAAE,OAAO,IAAI;AACnB,iBAAW,IAAI,KAAK,OAAO,CAAC,QAA2B,SAAS,GAAG,CAAC;AAAA,IACtE,OAAO;AACL,iBAAW,IAAI;AAAA,IACjB;AACA,WAAO;AAAA,MACL,MAAM,SAAS,IAAI,CAAC,MAAyB,EAAE,IAAI,EAAE,OAAO,CAAC,SAAS,IAAI;AAAA,MAC1E,SAAS,IAAI;AAAA,IACf;AAAA,EACF;AACF;;;APvJO,IAAM,eAAN,MAAM,cAAa;AAAA,EAKxB,YACkB,SACA,MAChB;AAFgB;AACA;AAEhB,SAAK,WAAW,IAAI,mCAAgB;AAAA,MAClC,WAAW,KAAK;AAAA,MAChB,kBAAkB,KAAK;AAAA,MACvB,eAAe,KAAK;AAAA,IACtB,CAAC;AACD,SAAK,aAAa,IAAI,WAAW,KAAK,SAAS;AAAA,EACjD;AAAA,EAdO;AAAA,EAEC;AAAA,EAcR,aAAa,IAAI,SAAuB,SAAiB;AACvD,UAAM,OAAO,MAAM,QAAQ,QAAQ,oBAAoB,OAAO;AAC9D,UAAM,KAAK,IAAI,cAAa,SAAS,IAAI;AACzC,QAAI,GAAG,YAAY,SAAS;AAC1B,YAAM,IAAI,MAAM,mCAAmC;AAAA,IACrD;AAAA,EACF;AAAA,EAEA,MAAM,aAAmC;AACvC,UAAM,WAAW,MAAM,KAAK,UAAU,eAAe,EAAE,OAAO,KAAK,QAAQ,CAAC;AAC5E,WAAO,QAAQ;AAAA,MACb,SAAS,IAAI,OAAO,YAAgC;AAClD,cAAM,OAAO,MAAM,KAAK,WAAW,YAAY,QAAQ,QAAQ;AAC/D,cAAM,kBAAkB,QAAQ,cAAc,SAC1C,OAAO,QAAQ,YAAY,IAAI,OAAO,QAAQ,cAAc,MAAM,IAClE,OAAO,QAAQ,YAAY;AAE/B,eAAO;AAAA,UACL,UAAM,kCAAmB,QAAQ,QAAQ;AAAA,UACzC,SAAS,OAAO,eAAe;AAAA,UAC/B,UAAU;AAAA,QACZ;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EAEA,MAAM,aAAa,SAAwD;AACzE,UAAM,0BAA0B;AAAA,MAC9B,QAAQ,CAAC,WAA8B,CAAC,QAAQ,MAAM,MAAM,WAAW,iBAAiB;AAAA,MACxF,GAAG;AAAA,IACL;AACA,WAAO,mBAAmB,KAAK,WAAW,KAAK,SAAS,uBAAuB;AAAA,EACjF;AAAA,EAEA,MAAM,qBAAqD;AACzD,UAAM,MAAM,MAAM,KAAK,QAAQ,uBAAuB,EAAE,cAAc,KAAK,QAAQ,CAAC;AACpF,QAAI,CAAC,IAAI,SAAS;AAChB,aAAO;AAAA,IACT;AAEA,UAAM,YAAY,IAAI;AACtB,UAAM,gBAAgB,IAAI;AAE1B,WAAO;AAAA,MACL,QAAQ,mCAAgB;AAAA,MACxB,WACE,cAAc,UAAU,YACpB,uCAAoB,OAAO,KAAK,OAChC,uCAAoB,OAAO,OAAO;AAAA,MACxC,WAAW,UAAU;AAAA,MACrB,SAAS,UAAU;AAAA,MACnB,QAAQ,UAAU;AAAA,MAClB,WAAW,UAAU;AAAA,MACrB,gBAAgB,UAAU;AAAA,MAC1B,SAAS,UAAU;AAAA,MACnB,OAAO,UAAU;AAAA,MACjB,cAAc,UAAU;AAAA,MACxB,cAAc,eAAe,UAAU;AAAA,MACvC,eAAe,eAAe,WAAW;AAAA,MACzC,aAAa,eAAe,SAAS,CAAC;AAAA,IACxC;AAAA,EACF;AAAA,EAEA,MAAM,mBAAmB,YAAyB;AAChD,WAAO,KAAK,QAAQ,uBAAuB;AAAA,MACzC,cAAc,KAAK;AAAA,MACnB,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,iBAAiB,YAAyB;AAC9C,WAAO,KAAK,QAAQ,oBAAoB,EAAE,cAAc,KAAK,SAAS,GAAG,WAAW,CAAC;AAAA,EACvF;AAAA,EAEA,MAAM,wBAAwB;AAC5B,WAAO,KAAK,QAAQ,yBAAyB,KAAK,OAAO;AAAA,EAC3D;AAAA,EAEA,MAAM,qBAAqB;AACzB,WAAO,KAAK,QAAQ,sBAAsB,KAAK,OAAO;AAAA,EACxD;AAAA,EAEA,MAAM,iBAAiB,OAAqE;AAC1F,UAAM,UAAU,wCAAqB,wBAAwB;AAAA,MAC3D,cAAc,KAAK;AAAA,MACnB,WAAW,MAAM;AAAA,MACjB,IAAI,MAAM;AAAA,IACZ,CAAC;AACD,UAAM,YAAY,MAAM,KAAK,OAAO,oBAAoB;AAAA,MACtD,YAAY;AAAA,IACd,CAAC;AAED,UAAM,KAAK,QAAQ,iBAAiB;AAAA,MAClC,GAAG;AAAA,MACH,cAAc,KAAK;AAAA,MACnB,WAAW,UAAU;AAAA,IACvB,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,6BAA6B,WAAkC;AACnE,UAAM,KAAK,MAAM,KAAK,mBAAmB;AACzC,WAAO,KAAK,iBAAiB;AAAA,MAC3B,aAAa;AAAA,MACb,QAAQ,mCAAgB;AAAA,MACxB,WAAW,uCAAoB,OAAO,KAAK;AAAA,MAC3C,gBAAgB;AAAA,MAChB;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,+BAA+B,WAAoC;AACvE,cAAM,2CAAuB,KAAK,WAAW,WAAW,KAAK,OAAO;AACpE,UAAM,KAAK,MAAM,KAAK,mBAAmB;AACzC,WAAO,KAAK,iBAAiB;AAAA,MAC3B,aAAa;AAAA,MACb,QAAQ,mCAAgB;AAAA,MACxB,WAAW,uCAAoB,OAAO,OAAO;AAAA,MAC7C,gBAAgB;AAAA,MAChB;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,mBAAmB,QAAgB,SAAiB;AACxD,UAAM,eAAe,gBAAgB,OAAO;AAC5C,UAAM,YAAY,MAAM,KAAK,OAAO,qBAAqB,EAAE,kBAAkB,aAAa,CAAC;AAC3F,WAAO,KAAK,QAAQ,mBAAmB;AAAA,MACrC,cAAc,KAAK;AAAA,MACnB;AAAA,MACA,WAAW,UAAU;AAAA,IACvB,CAAC;AAAA,EACH;AAAA;AAAA;AAAA,EAIA,MAAM,0BAA0B,WAAwB;AACtD,UAAM,MAAM,IAAI,qCAAiB;AACjC,UAAM,UAAU,MAAM,IAAI,MAAM,EAAE,QAAQ,KAAK,UAAU,CAAC;AAC1D,UAAM,SAAS,MAAM,IAAI,UAAU,EAAE,QAAQ,KAAK,UAAU,CAAC;AAC7D,UAAM,YAAY,MAAM,KAAK,OAAO,qBAAqB,EAAE,kBAAkB,QAAQ,CAAC;AACtF,WAAO,KAAK,QAAQ,0BAA0B;AAAA,MAC5C,cAAc,KAAK;AAAA,MACnB,aAAa,MAAM,KAAK,YAAY;AAAA,MACpC;AAAA,MACA;AAAA,MACA,WAAW,UAAU;AAAA,IACvB,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,kBAAkB;AACtB,UAAM,YAAY,MAAM,KAAK,mBAAmB;AAChD,QAAI,CAAC,aAAa,UAAU,iBAAiB,IAAI;AAC/C,YAAM,IAAI,MAAM,kBAAkB;AAAA,IACpC;AAEA,UAAM,kBAAkB,UAAU;AAClC,UAAM,gBAAY,mCAAe,KAAK,SAAS,eAAe;AAC9D,UAAM,SAAS,MAAM,UAAU,UAAU,EAAE,QAAQ,KAAK,UAAU,CAAC;AACnE,UAAM,UAAU,MAAM,UAAU,MAAM,EAAE,QAAQ,KAAK,UAAU,CAAC;AAChE,UAAM,YAAY,MAAM,KAAK,OAAO,qBAAqB,EAAE,kBAAkB,QAAQ,CAAC;AACtF,WAAO,KAAK,QAAQ,gBAAgB;AAAA,MAClC,cAAc,KAAK;AAAA,MACnB;AAAA,MACA,WAAW,UAAU;AAAA,IACvB,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,oCAAoC;AACxC,WAAO,KAAK,QAAQ,kCAAkC,EAAE,cAAc,KAAK,QAAQ,CAAC;AAAA,EACtF;AAAA,EAEA,MAAM,0BAA0B;AAC9B,WAAO,KAAK,QAAQ,wBAAwB,EAAE,cAAc,KAAK,QAAQ,CAAC;AAAA,EAC5E;AAAA,EAEA,MAAM,oBAA+C;AAEnD,UAAM,MAAM,IAAI,qCAAiB;AACjC,QAAI,UAAU,KAAK,OAAO;AAC1B,QAAI,CAAC,IAAI,UAAU,UAAU,OAAO;AAClC,YAAM,SAAS,MAAM,KAAK,UAAU,qBAAqB;AACzD,UAAI,YAAY,MAAM;AAAA,IACxB;AACA,UAAM,UAAU,MAAM,IAAI,MAAM,EAAE,QAAQ,KAAK,UAAU,CAAC;AAC1D,UAAM,eAAe,MAAM,KAAK,UAAU,uBAAuB,EAAE,kBAAkB,QAAQ,CAAC;AAE9F,UAAM,UAAU,aAAa,QAAQ,OAAO,WAAW;AACvD,UAAM,WAAW,aAAa,QAAQ,OAAO;AAC7C,UAAM,WAAW,OAAO,IAAI,UAAU,UAAU,KAAe;AAC/D,UAAM,EAAE,QAAQ,IAAI,aAAa;AAEjC,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,iBAAiB,SAAoB;AACzC,QAAI;AACJ,QAAI;AACJ,QAAI,QAAQ,MAAM,UAAU,KAAK,KAAK,WAAW;AAC/C,gBAAU,IAAI,IAAI,QAAQ,MAAM,IAAI,CAAC,SAAS,CAAC,KAAK,aAAa,KAAK,SAAS,CAAC,CAAC;AACjF,gBAAU,QAAQ;AAAA,IACpB,WAAW,QAAQ,eAAe,QAAQ,iBAAiB,QAAQ,aAAa,UAAU,KAAK,KAAK,WAAW;AAC7G,gBAAU,IAAI,IAAI,QAAQ,YAAY,IAAI,CAAC,SAAS,CAAC,KAAK,aAAa,KAAK,SAAS,CAAC,CAAC;AACvF,gBAAU,QAAQ;AAAA,IACpB,OAAO;AACL,YAAM,IAAI,MAAM,uBAAuB;AAAA,IACzC;AAEA,UAAM,OAA8B,CAAC;AACrC,aAAS,IAAI,GAAG,IAAI,KAAK,KAAK,OAAO,QAAQ,KAAK;AAChD,YAAM,QAAQ,KAAK,KAAK,OAAO,CAAC;AAChC,YAAM,YAAY,QAAQ,IAAI,MAAM,OAAO;AAC3C,UAAI,WAAW;AACb,aAAK,KAAK,SAAS;AAAA,MACrB;AAAA,IACF;AACA,UAAM,iBAAiB,KAAK,SAAS,yBAAyB,IAAI;AAClE,WAAO,KAAK,UAAU,wBAAwB;AAAA,MAC5C,kBAAkB,gBAAgB,OAAO;AAAA,MACzC,WAAW;AAAA,MACX,SAAS,EAAE,aAAa,KAAK;AAAA,IAC/B,CAAC;AAAA,EACH;AAAA,EAEA,IAAI,UAAU;AACZ,WAAO,KAAK,SAAS;AAAA,EACvB;AAAA,EAEA,IAAY,UAAU;AACpB,WAAO,KAAK,QAAQ;AAAA,EACtB;AAAA,EAEA,IAAY,SAAS;AACnB,WAAO,KAAK,QAAQ;AAAA,EACtB;AAAA,EAEA,MAAc,cAAc;AAC1B,WAAO,KAAK,QAAQ,OAAO,QAAQ;AAAA,EACrC;AAAA,EAEA,IAAY,YAAY;AACtB,WAAO,KAAK,QAAQ;AAAA,EACtB;AACF;;;AQ1RO,IAAM,kBAAN,MAAsB;AAAA,EAG3B,YAA4B,SAAuB;AAAvB;AAC1B,SAAK,kBAAkB,oBAAI,IAAuB;AAAA,EACpD;AAAA,EAJQ;AAAA,EAMR,MAAM,aAAa,SAAiB;AAClC,UAAM,SAAS,KAAK,gBAAgB,IAAI,OAAO;AAC/C,QAAI,QAAQ;AACV,aAAO;AAAA,IACT;AACA,UAAM,KAAK,MAAM,KAAK,cAAc,OAAO;AAC3C,QAAI,IAAI;AACN,WAAK,gBAAgB,IAAI,SAAS,EAAE;AAAA,IACtC;AACA,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,kBAAkB,WAAyD;AAC/E,UAAM,UAAqC,IAAI,MAAM,UAAU,MAAM,EAAE,KAAK,MAAS;AAGrF,aAAS,IAAI,GAAG,IAAI,UAAU,QAAQ,KAAK;AACzC,YAAM,UAAU,UAAU,CAAC;AAC3B,cAAQ,CAAC,IAAI,KAAK,gBAAgB,IAAI,OAAO;AAAA,IAC/C;AAGA,UAAM,eAAe,QAClB,IAAI,CAAC,MAAM,UAAW,SAAS,SAAY,QAAQ,EAAG,EACtD,OAAO,CAAC,UAAU,UAAU,EAAE;AACjC,QAAI,aAAa,WAAW,GAAG;AAC7B,aAAO;AAAA,IACT;AACA,UAAM,gBAAgB,MAAM,KAAK,QAAQ,QAAQ,kBAAkB,aAAa,IAAI,CAAC,UAAU,UAAU,KAAK,CAAC,CAAC;AAChH,aAAS,IAAI,GAAG,IAAI,aAAa,QAAQ,KAAK;AAC5C,YAAM,QAAQ,aAAa,CAAC;AAC5B,cAAQ,KAAK,IAAI,cAAc,CAAC;AAAA,IAClC;AAGA,aAAS,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;AACvC,UAAI,QAAQ,CAAC,MAAM,QAAW;AAC5B,gBAAQ,CAAC,IAAI,MAAM,KAAK,sBAAsB,UAAU,CAAC,CAAC;AAAA,MAC5D;AAAA,IACF;AAGA,aAAS,IAAI,GAAG,IAAI,UAAU,QAAQ,KAAK;AACzC,UAAI,QAAQ,CAAC,GAAG;AACd,aAAK,gBAAgB,IAAI,UAAU,CAAC,GAAG,QAAQ,CAAC,CAAc;AAAA,MAChE;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA,EAEA,MAAc,cAAc,SAAiB;AAC3C,UAAM,YAAY,MAAM,KAAK,wBAAwB,OAAO;AAC5D,QAAI,WAAW;AACb,aAAO;AAAA,IACT;AACA,UAAM,UAAU,MAAM,KAAK,sBAAsB,OAAO;AACxD,QAAI,SAAS;AACX,aAAO;AAAA,IACT;AACA,WAAO;AAAA,EACT;AAAA,EAEA,MAAc,wBAAwB,SAAiD;AACrF,QAAI;AACF,YAAM,KAAK,MAAM,KAAK,QAAQ,QAAQ,aAAa,OAAO;AAC1D,aAAO;AAAA,IACT,SAAS,GAAG;AACV,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEA,MAAc,sBAAsB,SAAiD;AACnF,WAAO,sBAAsB,KAAK,QAAQ,WAAW,OAAO;AAAA,EAC9D;AACF;;;AC1FA,oBAA0B;;;ACA1B,IAAAC,qBA8BO;AAGP,mBAAkB;AAIX,IAAM,cAAN,MAAM,aAAgC;AAAA,EAG3C,YAA6B,QAAgB;AAAhB;AAAA,EAAiB;AAAA,EAFtC;AAAA,EAIR,MAAM,SAAS,OAAyC;AACtD,UAAM,MAAM,MAAM,aAAAC,QAAM,KAAqB,GAAG,KAAK,MAAM,eAAe,KAAK;AAE/E,QAAI,IAAI,WAAW,OAAO,IAAI,WAAW,KAAK;AAC5C,YAAM,IAAI,MAAM,4BAA4B,GAAG,EAAE;AAAA,IACnD;AACA,SAAK,SAAS,IAAI,KAAK;AACvB,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,MAAM,YAAY,KAAiC;AACjD,QAAI;AACF,YAAM,MAAM,MAAM,aAAAA,QAAM,IAAI,GAAG,KAAK,MAAM,SAAS,EAAE,SAAS,KAAK,QAAQ,GAAG,EAAE,CAAC;AACjF,aAAO,IAAI,WAAW;AAAA,IACxB,SAAS,GAAG;AACV,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEA,YAAY,OAAiB;AAC3B,SAAK,SAAS;AAAA,EAChB;AAAA,EAEA,MAAM,aAAa,SAAiD;AAClE,YAAQ,MAAM,KAAK,kBAAkB,CAAC,OAAO,CAAC,GAAG,CAAC;AAAA,EACpD;AAAA,EAEA,MAAM,kBAAkB,WAAyD;AAC/E,UAAM,QAAiC;AAAA,MACrC,iBAAiB;AAAA,IACnB;AACA,UAAM,MAAM,MAAM,aAAAA,QAAM,IAA4B,GAAG,KAAK,MAAM,qBAAqB;AAAA,MACrF,QAAQ;AAAA,MACR,SAAS,KAAK,QAAQ;AAAA,IACxB,CAAC;AAGD,QAAI,IAAI,WAAW,OAAO,IAAI,WAAW,KAAK;AAC5C,YAAM,IAAI,MAAM,qCAAqC,GAAG,EAAE;AAAA,IAC5D;AACA,WAAO,IAAI,MAAM;AAAA,MAAI,CAAC,wBACpB,sBAAsB,kCAAe,GAAG,mBAAmB,IAAI;AAAA,IACjE;AAAA,EACF;AAAA,EAEA,MAAM,oBAAoB,cAA6C;AACrE,UAAM,IAAoB;AAAA,MACxB;AAAA,IACF;AACA,UAAM,MAAM,MAAM,aAAAA,QAAM,IAAoB,GAAG,KAAK,MAAM,UAAU;AAAA,MAClE,QAAQ;AAAA,MACR,SAAS,KAAK,QAAQ;AAAA,IACxB,CAAC;AAED,QAAI,IAAI,WAAW,OAAO,IAAI,WAAW,KAAK;AAC5C,YAAM,IAAI,MAAM,qCAAqC,GAAG,EAAE;AAAA,IAC5D;AACA,WAAO,aAAY,cAAc,IAAI,IAAI;AAAA,EAC3C;AAAA,EAEA,MAAM,cAAsC;AAC1C,UAAM,UAAU,MAAM,aAAAA,QAAM,IAAmB,GAAG,KAAK,MAAM,SAAS;AAAA,MACpE,SAAS,KAAK,QAAQ;AAAA,IACxB,CAAC;AAED,QAAI,QAAQ,WAAW,OAAO,QAAQ,WAAW,KAAK;AACpD,YAAM,IAAI,MAAM,qCAAqC,OAAO,EAAE;AAAA,IAChE;AACA,WAAO,QAAQ;AAAA,EACjB;AAAA,EAEA,MAAM,sBAAsB,OAGY;AACtC,UAAM,IAAqB;AAAA,MACzB,QAAQ,MAAM,UAAU,mCAAgB;AAAA,MACxC,GAAI,MAAM,aACN;AAAA,QACE,MAAM,MAAM,WAAW,KAAK,SAAS;AAAA,QACrC,OAAO,MAAM,WAAW,MAAM,SAAS;AAAA,MACzC,IACA,CAAC;AAAA,IACP;AACA,UAAM,MAAM,MAAM,aAAAA,QAAM,IAAkC,GAAG,KAAK,MAAM,gBAAgB;AAAA,MACtF,QAAQ;AAAA,MACR,SAAS,KAAK,QAAQ;AAAA,IACxB,CAAC;AACD,QAAI,IAAI,WAAW,OAAO,IAAI,WAAW,KAAK;AAC5C,YAAM,IAAI,MAAM,yCAAyC,GAAG,EAAE;AAAA,IAChE;AACA,WAAO;AAAA,MACL,MAAM,IAAI,KAAK,KAAK,IAAI,aAAY,aAAa;AAAA,MACjD,MAAM,IAAI,KAAK;AAAA,IACjB;AAAA,EACF;AAAA,EAEA,MAAM,kBAAkB,OAAyE;AAC/F,UAAM,IAA2B;AACjC,UAAM,MAAM,MAAM,aAAAA,QAAM,KAAK,GAAG,KAAK,MAAM,iBAAiB,GAAG,EAAE,SAAS,KAAK,QAAQ,EAAE,CAAC;AAC1F,QAAI,IAAI,WAAW,OAAO,IAAI,WAAW,KAAK;AAC5C,YAAM,IAAI,MAAM,qCAAqC,GAAG,EAAE;AAAA,IAC5D;AAAA,EACF;AAAA,EAEA,MAAM,uBAAuB,OAA8E;AACzG,UAAM,MAAM,MAAM,aAAAA,QAAM,IAAmC,GAAG,KAAK,MAAM,wBAAwB;AAAA,MAC/F,QAAQ;AAAA,MACR,SAAS,KAAK,QAAQ;AAAA,IACxB,CAAC;AACD,QAAI,IAAI,WAAW,OAAO,IAAI,WAAW,KAAK;AAC5C,YAAM,IAAI,MAAM,qCAAqC,GAAG,EAAE;AAAA,IAC5D;AACA,WAAO,IAAI;AAAA,EACb;AAAA,EAEA,MAAM,uBAAuB,OAAgF;AAC3G,UAAM,MAAM,MAAM,aAAAA,QAAM,IAAoC,GAAG,KAAK,MAAM,wBAAwB;AAAA,MAChG,QAAQ;AAAA,MACR,SAAS,KAAK,QAAQ;AAAA,IACxB,CAAC;AACD,QAAI,IAAI,WAAW,OAAO,IAAI,WAAW,KAAK;AAC5C,YAAM,IAAI,MAAM,4CAA4C,GAAG,EAAE;AAAA,IACnE;AACA,WAAO,IAAI;AAAA,EACb;AAAA,EAEA,MAAM,oBAAoB,OAAyE;AACjG,UAAM,MAAM,MAAM,aAAAA,QAAM,IAAsC,GAAG,KAAK,MAAM,0BAA0B;AAAA,MACpG,QAAQ;AAAA,MACR,SAAS,KAAK,QAAQ;AAAA,IACxB,CAAC;AACD,QAAI,IAAI,WAAW,OAAO,IAAI,WAAW,KAAK;AAC5C,YAAM,IAAI,MAAM,4CAA4C,GAAG,EAAE;AAAA,IACnE;AACA,WAAO,IAAI;AAAA,EACb;AAAA,EAEA,MAAM,yBAAyB,SAAkC;AAC/D,UAAM,MAAM,MAAM,aAAAA,QAAM,IAAY,GAAG,KAAK,MAAM,2BAA2B;AAAA,MAC3E,QAAQ;AAAA,QACN,cAAc;AAAA,MAChB;AAAA,MACA,SAAS,KAAK,QAAQ;AAAA,IACxB,CAAC;AACD,QAAI,IAAI,WAAW,OAAO,IAAI,WAAW,KAAK;AAC5C,YAAM,IAAI,MAAM,4CAA4C,GAAG,EAAE;AAAA,IACnE;AACA,WAAO,IAAI;AAAA,EACb;AAAA,EAEA,MAAM,sBAAsB,SAAkC;AAC5D,UAAM,MAAM,MAAM,aAAAA,QAAM,IAAY,GAAG,KAAK,MAAM,wBAAwB;AAAA,MACxE,QAAQ;AAAA,QACN,cAAc;AAAA,MAChB;AAAA,MACA,SAAS,KAAK,QAAQ;AAAA,IACxB,CAAC;AACD,QAAI,IAAI,WAAW,OAAO,IAAI,WAAW,KAAK;AAC5C,YAAM,IAAI,MAAM,yCAAyC,GAAG,EAAE;AAAA,IAChE;AACA,WAAO,IAAI;AAAA,EACb;AAAA,EAEA,MAAM,mBAAmB,OAAuC;AAC9D,UAAM,MAAM,MAAM,aAAAA,QAAM,KAAK,GAAG,KAAK,MAAM,iBAAiB,OAAO;AAAA,MACjE,SAAS,KAAK,QAAQ;AAAA,IACxB,CAAC;AACD,QAAI,IAAI,WAAW,OAAO,IAAI,WAAW,KAAK;AAC5C,YAAM,IAAI,MAAM,sCAAsC,GAAG,EAAE;AAAA,IAC7D;AAAA,EACF;AAAA,EAEA,MAAM,iBAAiB,OAAgD;AACrE,UAAM,MAAM,MAAM,aAAAA,QAAM,KAAK,GAAG,KAAK,MAAM,0BAA0B,OAAO,EAAE,SAAS,KAAK,QAAQ,EAAE,CAAC;AACvG,QAAI,IAAI,WAAW,OAAO,IAAI,WAAW,KAAK;AAC5C,YAAM,IAAI,MAAM,oCAAoC,GAAG,EAAE;AAAA,IAC3D;AAAA,EACF;AAAA;AAAA;AAAA,EAIA,MAAM,0BAA0B,QAMd;AAChB,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,gBAAgB,OAAgC;AACpD,UAAM,MAAM,MAAM,aAAAA,QAAM,KAAK,GAAG,KAAK,MAAM,+BAA+B,OAAO;AAAA,MAC/E,SAAS,KAAK,QAAQ;AAAA,IACxB,CAAC;AACD,QAAI,IAAI,WAAW,OAAO,IAAI,WAAW,KAAK;AAC5C,YAAM,IAAI,MAAM,sCAAsC,GAAG,EAAE;AAAA,IAC7D;AAAA,EACF;AAAA,EAEA,MAAM,mBAAmB,OAAgC;AACvD,UAAM,MAAM,MAAM,aAAAA,QAAM,KAAK,GAAG,KAAK,MAAM,6BAA6B,OAAO;AAAA,MAC7E,SAAS,KAAK,QAAQ;AAAA,IACxB,CAAC;AACD,QAAI,IAAI,WAAW,OAAO,IAAI,WAAW,KAAK;AAC5C,YAAM,IAAI,MAAM,sCAAsC,GAAG,EAAE;AAAA,IAC7D;AAAA,EACF;AAAA,EAEA,MAAM,kCAAkC,OAAiC;AACvE,UAAM,MAAM,MAAM,aAAAA,QAAM,KAAK,GAAG,KAAK,MAAM,8BAA8B,OAAO,EAAE,SAAS,KAAK,QAAQ,EAAE,CAAC;AAC3G,QAAI,IAAI,WAAW,OAAO,IAAI,WAAW,KAAK;AAC5C,YAAM,IAAI,MAAM,qDAAqD,GAAG,EAAE;AAAA,IAC5E;AAAA,EACF;AAAA,EAEA,MAAM,wBAAwB,OAA8B;AAC1D,UAAM,MAAM,MAAM,aAAAA,QAAM,KAAK,GAAG,KAAK,MAAM,6BAA6B,OAAO,EAAE,SAAS,KAAK,QAAQ,EAAE,CAAC;AAC1G,QAAI,IAAI,WAAW,OAAO,IAAI,WAAW,KAAK;AAC5C,YAAM,IAAI,MAAM,2CAA2C,GAAG,EAAE;AAAA,IAClE;AAAA,EACF;AAAA,EAEA,MAAM,sBAAsB,YAA2D;AACrF,UAAM,MAAM,MAAM,aAAAA,QAAM,IAA2B,GAAG,KAAK,MAAM,iBAAiB;AAAA,MAChF,SAAS,KAAK,QAAQ;AAAA,MACtB,QAAQ;AAAA,IACV,CAAC;AACD,QAAI,IAAI,WAAW,KAAK;AACtB,YAAM,IAAI,MAAM,gCAAgC,GAAG,EAAE;AAAA,IACvD;AACA,WAAO,IAAI;AAAA,EACb;AAAA,EAEA,MAAM,kBAAkB,OAA8E;AACpG,UAAM,MAAM,MAAM,aAAAA,QAAM,KAAK,GAAG,KAAK,MAAM,iBAAiB,OAAO,EAAE,SAAS,KAAK,QAAQ,EAAE,CAAC;AAC9F,QAAI,IAAI,WAAW,OAAO,IAAI,WAAW,KAAK;AAC5C,YAAM,IAAI,MAAM,qCAAqC,GAAG,EAAE;AAAA,IAC5D;AAAA,EACF;AAAA;AAAA,EAGA,MAAM,2BAA2B,SAAiB;AAChD,WAAO;AAAA,EACT;AAAA,EAEQ,QAAQ,OAAgB;AAC9B,WAAO,EAAE,eAAe,UAAU,SAAS,KAAK,MAAM,GAAG;AAAA,EAC3D;AAAA,EAEA,OAAe,cAAc,MAAoC;AAC/D,WAAO;AAAA,MACL,GAAG;AAAA,MACH,QAAQ,KAAK,OAAO,IAAI,CAAC,WAAW;AAAA,QAClC,SAAS,MAAM;AAAA,QACf,QAAQ,MAAM;AAAA,QACd,WAAW,kCAAe,GAAG;AAAA,UAC3B,kBAAkB,MAAM;AAAA,UACxB,QAAQ,MAAM;AAAA,QAChB,CAAC;AAAA,MACH,EAAE;AAAA,IACJ;AAAA,EACF;AACF;;;AClTO,IAAK,WAAL,kBAAKC,cAAL;AACL,EAAAA,UAAA,WAAQ;AACR,EAAAA,UAAA,UAAO;AACP,EAAAA,UAAA,SAAM;AACN,EAAAA,UAAA,UAAO;AACP,EAAAA,UAAA,UAAO;AALG,SAAAA;AAAA,GAAA;AA0BL,IAAM,oBAAoB;AAE1B,IAAM,kBAAkB;AACxB,IAAM,kBAAkB;AAExB,IAAM,gBAAgB;AACtB,IAAM,oBAAoB;AAE1B,IAAM,cAAc;AACpB,IAAM,kBAAkB;AAExB,IAAM,cAAc,oBAAI,IAA2B;AAAA,EACxD;AAAA,IACE;AAAA,IACA;AAAA,MACE,WAAW;AAAA,QACT,KAAK;AAAA,MACP;AAAA,MACA,SAAS;AAAA,QACP,KAAK;AAAA,MACP;AAAA,MACA,YAAY;AAAA,IACd;AAAA,EACF;AAAA,EACA;AAAA,IACE;AAAA,IACA;AAAA,MACE,WAAW;AAAA,QACT,KAAK;AAAA,MACP;AAAA,MACA,SAAS;AAAA,QACP,KAAK;AAAA,MACP;AAAA,MACA,YAAY;AAAA,IACd;AAAA,EACF;AAAA,EACA;AAAA,IACE;AAAA,IACA;AAAA,MACE,WAAW;AAAA,QACT,KAAK;AAAA,MACP;AAAA,MACA,SAAS;AAAA,QACP,KAAK;AAAA,MACP;AAAA,MACA,YAAY;AAAA,IACd;AAAA,EACF;AACF,CAAC;AAEM,SAAS,eAAe,KAAe,SAA8B;AAC1E,QAAM,SAAS,YAAY,IAAI,GAAG;AAClC,MAAI,CAAC,QAAQ;AACX,UAAM,IAAI,MAAM,qBAAqB;AAAA,EACvC;AACA,MAAI,SAAS,WAAW,KAAK;AAC3B,WAAO,UAAU,MAAM,QAAQ,UAAU;AAAA,EAC3C;AACA,MAAI,SAAS,SAAS,KAAK;AACzB,WAAO,QAAQ,MAAM,QAAQ,QAAQ;AAAA,EACvC;AACA,SAAO;AACT;;;AFjFO,IAAM,eAAN,MAAM,cAAa;AAAA,EACR;AAAA,EAEA;AAAA,EAEA;AAAA,EAEhB;AAAA,EAEA,YAAY,OAAyE;AACnF,SAAK,UAAU,MAAM;AACrB,SAAK,YAAY,MAAM;AACvB,SAAK,SAAS,MAAM;AAAA,EACtB;AAAA,EAEA,aAAa,IAAI,KAAe,SAA8B;AAC5D,UAAM,SAAS,eAAe,KAAK,OAAO;AAC1C,UAAM,YAAY,IAAI,wBAAU,OAAO,SAAS;AAChD,UAAM,UAAU,IAAI,YAAY,OAAO,QAAQ,GAAG;AAClD,WAAO,IAAI,cAAa;AAAA,MACtB;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,cAAc,QAAiB;AAC7B,SAAK,UAAU;AAAA,EACjB;AAAA,EAEA,IAAI,SAAS;AACX,QAAI,CAAC,KAAK,SAAS;AACjB,YAAM,IAAI,MAAM,sBAAsB;AAAA,IACxC;AACA,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,IAAI,OAAO,KAAc;AACvB,SAAK,UAAU;AAAA,EACjB;AACF;;;AZ5BO,IAAM,cAAN,MAAM,aAAY;AAAA,EAKvB,YAA4B,SAAuB;AAAvB;AAAA,EAAwB;AAAA,EAJ5C;AAAA,EAEA;AAAA,EAIR,aAAa,IAAI,KAAe,SAA8B;AAC5D,UAAM,UAAU,MAAM,aAAa,IAAI,KAAK,OAAO;AACnD,WAAO,IAAI,aAAY,OAAO;AAAA,EAChC;AAAA,EAEA,MAAM,cAAc,OAAoE;AACtF,QAAI,MAAM,UAAU;AAClB,YAAM,WAAW,MAAM,KAAK,QAAQ,YAAY,MAAM,QAAQ;AAC9D,UAAI,UAAU;AACZ,aAAK,QAAQ,SAAS,MAAM;AAC5B,aAAK,QAAQ,YAAY,MAAM,QAAQ;AACvC,eAAO,MAAM;AAAA,MACf;AAAA,IACF;AACA,UAAM,MAAM,MAAM,KAAK,SAAS,MAAM,MAAM;AAC5C,SAAK,QAAQ,SAAS,MAAM;AAC5B,SAAK,QAAQ,YAAY,GAAG;AAC5B,WAAO;AAAA,EACT;AAAA,EAEA,MAAc,SAAS,QAAoC;AACzD,UAAM,aAAa,wCAAqB,2BAA0B,oBAAI,KAAK,GAAE,YAAY,CAAC;AAC1F,UAAM,MAAM,MAAM,OAAO,oBAAoB;AAAA,MAC3C;AAAA,IACF,CAAC;AACD,WAAO,KAAK,QAAQ,SAAS;AAAA,MAC3B,SAAS,MAAM,OAAO,QAAQ;AAAA,MAC9B,SAAS;AAAA,MACT,WAAW,IAAI;AAAA,MACf,YAAY,OAAO;AAAA,IACrB,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,WAAW;AACf,WAAO,KAAK,QAAQ,QAAQ,YAAY;AAAA,EAC1C;AAAA,EAEA,MAAM,WAAW,YAAgE;AAC/E,WAAO,KAAK,QAAQ,QAAQ,sBAAsB,EAAE,QAAQ,mCAAgB,QAAQ,WAAW,CAAC;AAAA,EAClG;AAAA,EAEA,MAAM,cAAc,MAAuB;AACzC,WAAO,KAAK,eAAe,oBAAoB,IAAI;AAAA,EACrD;AAAA,EAEA,gBAAgB,MAAoB;AAClC,WAAO,IAAI,aAAa,KAAK,SAAS,IAAI;AAAA,EAC5C;AAAA,EAEA,MAAM,2BAA2B,cAAsB;AACrD,UAAM,OAAO,MAAM,KAAK,QAAQ,oBAAoB,YAAY;AAChE,WAAO,IAAI,aAAa,KAAK,SAAS,IAAI;AAAA,EAC5C;AAAA;AAAA;AAAA,EAIA,IAAI,iBAAiB;AACnB,QAAI,CAAC,KAAK,iBAAiB;AACzB,WAAK,kBAAkB,IAAI,aAAa,KAAK,SAAS,KAAK,eAAe;AAAA,IAC5E;AACA,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,IAAI,kBAAkB;AACpB,QAAI,CAAC,KAAK,kBAAkB;AAC1B,WAAK,mBAAmB,IAAI,gBAAgB,KAAK,OAAO;AAAA,IAC1D;AACA,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,IAAI,SAAS;AACX,WAAO,KAAK,QAAQ;AAAA,EACtB;AAAA,EAEA,IAAI,UAAU;AACZ,WAAO,KAAK,QAAQ;AAAA,EACtB;AAAA,EAEA,IAAI,SAAS;AACX,WAAO,KAAK,QAAQ;AAAA,EACtB;AAAA,EAEA,IAAI,cAA8B;AAChC,WAAO,IAAI,eAAe,KAAK,OAAO;AAAA,EACxC;AAAA,EAEA,IAAI,aAA4B;AAC9B,WAAO,IAAI,cAAc,KAAK,OAAO;AAAA,EACvC;AAAA,EAEA,MAAc,gBAAgB;AAC5B,WAAO,KAAK,OAAO,QAAQ;AAAA,EAC7B;AACF;","names":["import_sui3_utils","import_sui3_utils","import_sui3_utils","import_utils","import_utils","import_sui3_utils","import_sui3_utils","axios","MSafeEnv"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/core/CreateHelper.ts","../src/core/MSafeClient.ts","../src/core/AddressBookSDK.ts","../src/core/InvitationSDK.ts","../src/core/MSafeAccount.ts","../src/utils/buffer.ts","../src/utils/crypto.ts","../src/utils/format.ts","../src/utils/coin.ts","../src/utils/sui.ts","../src/utils/iter/iterator.ts","../src/utils/iter/object.ts","../src/core/PublicKeyHelper.ts","../src/globals/MSafeGlobals.ts","../src/backend/BackendImpl.ts","../src/globals/const.ts"],"sourcesContent":["export * from './core';\nexport * from './globals';\nexport * from './types';\nexport * from './utils';\n","import { MultiSigAccount, MultiSigConfig, PublicKeySerde, SigningMessageHelper } from '@msafe/sui3-utils';\nimport { PublicKey, SerializedSignature } from '@mysten/sui.js/cryptography';\n\nimport { PublicKeyHelper } from '@/core/PublicKeyHelper';\nimport { MSafeGlobals } from '@/globals/MSafeGlobals';\nimport { CreateMSafeInfo } from '@/types';\n\nexport class CreateHelper {\n constructor(\n public readonly globals: MSafeGlobals,\n public readonly pkHelper: PublicKeyHelper,\n ) {}\n\n async getPublicKeyBatch(addresses: string[]) {\n return this.pkHelper.getPublicKeyBatch(addresses);\n }\n\n async calculateMSafeAddress(info: CreateMSafeInfo) {\n const msConfig = await this.reduceCreationInfoToRawConfig(info);\n const ms = new MultiSigAccount(msConfig);\n return ms.address;\n }\n\n // Validate the create info and return the msafe address.\n async validateCreateInfo(createInfo: CreateMSafeInfo) {\n // Calculate the sui address will check the multi-sig\n return this.calculateMSafeAddress(createInfo);\n }\n\n async submitMSafeCreation(creationInfo: CreateMSafeInfo) {\n const msafeAddress = await this.validateCreateInfo(creationInfo);\n\n const signingMessage = SigningMessageHelper.createMSafeMessage(msafeAddress);\n const signature = await this.globals.wallet.signPersonalMessage({ messageStr: signingMessage });\n\n await this.submitToBackend(creationInfo, signature.signature);\n return msafeAddress;\n }\n\n private async reduceCreationInfoToRawConfig(info: CreateMSafeInfo): Promise<MultiSigConfig> {\n const publicKeys = await this.getPublicKeyBatch(info.owners.map((owner) => owner.address));\n publicKeys.forEach((pk, i) => {\n if (pk === undefined) {\n throw new Error(`Unknown public key for address: ${info.owners[i].address}`);\n }\n });\n return {\n threshold: info.threshold,\n ownersWithWeight: info.owners.map((owner, i) => ({\n publicKey: publicKeys[i] as PublicKey,\n weight: owner.weight,\n })),\n creationNonce: info.creationNonce,\n };\n }\n\n private async submitToBackend(createInfo: CreateMSafeInfo, signature: SerializedSignature) {\n const pks = await this.pkHelper.getPublicKeyBatch(createInfo.owners.map((owner) => owner.address));\n await this.globals.backend.createMSafeAccount({\n owners: createInfo.owners.map((owner, i) => ({\n address: owner.address,\n weight: owner.weight,\n ...PublicKeySerde.ser(pks[i] as PublicKey),\n })),\n threshold: createInfo.threshold,\n name: createInfo.name, // name validation is deferred to backend\n description: createInfo.description, // description validation is deferred to backend\n creationNonce: createInfo.creationNonce,\n signature,\n });\n }\n}\n","import {\n IMSafeConfig,\n IPagedResult,\n IPageOptions,\n JWTToken,\n SigningMessageHelper,\n UserMSafeStatus,\n} from '@msafe/sui3-utils';\n\nimport { AddressBookSDK } from '@/core/AddressBookSDK';\nimport { CreateHelper } from '@/core/CreateHelper';\nimport { InvitationSDK } from '@/core/InvitationSDK';\nimport { MSafeAccount } from '@/core/MSafeAccount';\nimport { PublicKeyHelper } from '@/core/PublicKeyHelper';\nimport { MSafeConfigOptions, MSafeEnv } from '@/globals/const';\nimport { MSafeGlobals } from '@/globals/MSafeGlobals';\nimport { CreateMSafeInfo } from '@/types';\nimport { IWallet } from '@/types/wallet';\n\nexport class MSafeClient {\n private _creationHelper: CreateHelper | undefined;\n\n private _publicKeyHelper: PublicKeyHelper | undefined;\n\n constructor(public readonly globals: MSafeGlobals) {}\n\n static async New(env: MSafeEnv, options?: MSafeConfigOptions) {\n const globals = await MSafeGlobals.New(env, options);\n return new MSafeClient(globals);\n }\n\n async connectWallet(input: { wallet: IWallet; jwtToken?: JWTToken }): Promise<JWTToken> {\n if (input.jwtToken) {\n const verified = await this.backend.verifyToken(input.jwtToken);\n if (verified) {\n this.globals.wallet = input.wallet;\n this.backend.setJWTToken(input.jwtToken);\n return input.jwtToken;\n }\n }\n const jwt = await this.authSign(input.wallet);\n this.globals.wallet = input.wallet;\n this.backend.setJWTToken(jwt);\n return jwt;\n }\n\n private async authSign(wallet: IWallet): Promise<JWTToken> {\n const messageStr = SigningMessageHelper.loginMessageWithTimestamp(new Date().toUTCString());\n const sig = await wallet.signPersonalMessage({\n messageStr,\n });\n return this.backend.authSign({\n address: await wallet.address(),\n message: messageStr,\n signature: sig.signature,\n walletType: wallet.walletType,\n });\n }\n\n async userInfo() {\n return this.globals.backend.getUserInfo();\n }\n\n async ownedMSafe(pagination?: IPageOptions): Promise<IPagedResult<IMSafeConfig>> {\n return this.globals.backend.getOwnedMSafeByStatus({ status: UserMSafeStatus.active, pagination });\n }\n\n async createAccount(info: CreateMSafeInfo) {\n return this.creationHelper.submitMSafeCreation(info);\n }\n\n getMSafeAccount(info: IMSafeConfig) {\n return new MSafeAccount(this.globals, info);\n }\n\n async getMSafeAccountFromAddress(msafeAddress: string) {\n const info = await this.backend.getMSafeAccountInfo(msafeAddress);\n return new MSafeAccount(this.globals, info);\n }\n\n // Get the creation helper to calculate the msafe account address,\n // validation, and more.\n get creationHelper() {\n if (!this._creationHelper) {\n this._creationHelper = new CreateHelper(this.globals, this.publicKeyHelper);\n }\n return this._creationHelper;\n }\n\n get publicKeyHelper() {\n if (!this._publicKeyHelper) {\n this._publicKeyHelper = new PublicKeyHelper(this.globals);\n }\n return this._publicKeyHelper;\n }\n\n get config() {\n return this.globals.config;\n }\n\n get backend() {\n return this.globals.backend;\n }\n\n get wallet() {\n return this.globals.wallet;\n }\n\n get AddressBook(): AddressBookSDK {\n return new AddressBookSDK(this.globals);\n }\n\n get Invitation(): InvitationSDK {\n return new InvitationSDK(this.globals);\n }\n\n private async walletAddress() {\n return this.wallet.address();\n }\n}\n","import { IPageOptions, SigningMessageHelper, UpdateAddressBookEntry } from '@msafe/sui3-utils';\n\nimport { MSafeGlobals } from '@/globals';\n\nexport class AddressBookSDK {\n constructor(public readonly globals: MSafeGlobals) {}\n\n async getEntries(pagination?: IPageOptions) {\n return this.globals.backend.getAddressBookEntries(pagination);\n }\n\n async update(updates: UpdateAddressBookEntry[]) {\n const messageStr = SigningMessageHelper.updateAddressBookMessage(updates);\n const sig = await this.globals.wallet.signPersonalMessage({ messageStr });\n return this.globals.backend.updateAddressBook({ updates, signature: sig.signature });\n }\n}\n","import { IMSafeConfig, IPagedResult, IPageOptions, UserMSafeStatus } from '@msafe/sui3-utils';\n\nimport { MSafeGlobals } from '@/globals';\n\nexport class InvitationSDK {\n constructor(public readonly globals: MSafeGlobals) {}\n\n async getMSafeByStatus(status: UserMSafeStatus, pagination?: IPageOptions): Promise<IPagedResult<IMSafeConfig>> {\n return this.globals.backend.getOwnedMSafeByStatus({ status, pagination });\n }\n\n async updateMSafeStatus(msafeAddress: string, status: UserMSafeStatus) {\n return this.globals.backend.updateMSafeStatus({ msafeAddress, status });\n }\n}\n","import {\n CoinTransferIntention,\n IMSafeConfig,\n IProposeIntentionRequest,\n MultiSigAccount,\n ObjectTransferIntention,\n SigningMessageHelper,\n TransactionDefaultApplication,\n TransactionSubTypes,\n TransactionType,\n TxIntention,\n buildObjectTransferTxb,\n buildRejectTxb,\n isSameAddress,\n} from '@msafe/sui3-utils';\nimport { SuiObjectData } from '@mysten/sui.js/client';\nimport { SerializedSignature } from '@mysten/sui.js/cryptography';\nimport { SuiObjectResponse } from '@mysten/sui.js/src/client';\nimport { TransactionBlock } from '@mysten/sui.js/transactions';\nimport { normalizeStructTag } from '@mysten/sui.js/utils';\n\nimport { MSafeGlobals } from '@/globals/MSafeGlobals';\nimport { OwnedCoin } from '@/types/assets';\nimport { Pagination, PendingTx, SimulationResult } from '@/types/msafe';\nimport { CoinHelper } from '@/utils';\nimport { HexToUint8Array } from '@/utils/buffer';\nimport { BatchObjectOptions, getAllOwnedObjects } from '@/utils/iter/object';\n\nexport class MSafeAccount {\n public multiSig: MultiSigAccount;\n\n private coinHelper: CoinHelper;\n\n constructor(\n public readonly globals: MSafeGlobals,\n public readonly info: IMSafeConfig,\n ) {\n this.multiSig = new MultiSigAccount({\n threshold: info.threshold,\n ownersWithWeight: info.owners,\n creationNonce: info.creationNonce,\n });\n this.coinHelper = new CoinHelper(this.suiClient);\n }\n\n static async New(globals: MSafeGlobals, address: string) {\n const info = await globals.backend.getMSafeAccountInfo(address);\n const ms = new MSafeAccount(globals, info);\n if (ms.address !== address) {\n throw new Error('Invalid msafe config with address');\n }\n }\n\n async ownedCoins(): Promise<OwnedCoin[]> {\n const balances = await this.suiClient.getAllBalances({ owner: this.address });\n return Promise.all(\n balances.map(async (balance): Promise<OwnedCoin> => {\n const meta = await this.coinHelper.getCoinMeta(balance.coinType);\n const unlockedBalance = balance.lockedBalance.number\n ? BigInt(balance.totalBalance) - BigInt(balance.lockedBalance.number)\n : BigInt(balance.totalBalance);\n\n return {\n type: normalizeStructTag(balance.coinType),\n balance: BigInt(unlockedBalance),\n metadata: meta,\n };\n }),\n );\n }\n\n async ownedObjects(options?: BatchObjectOptions): Promise<SuiObjectData[]> {\n const filterCoinObjectOptions = {\n filter: (objRes: SuiObjectResponse) => !objRes?.data?.type?.startsWith('0x2::coin::Coin'),\n ...options,\n };\n return getAllOwnedObjects(this.suiClient, this.address, filterCoinObjectOptions);\n }\n\n // TODO: Calculate the votes\n async pendingTransaction(): Promise<PendingTx | undefined> {\n const res = await this.backend.getPendingTransactions({ msafeAddress: this.address });\n if (!res.pending) {\n return undefined;\n }\n\n const pendingTx = res.pending;\n const rejectPending = res.reject;\n\n return {\n txType: TransactionType.Assets,\n txSubType:\n 'coinType' in pendingTx.intention\n ? TransactionSubTypes.assets.coin.send\n : TransactionSubTypes.assets.object.send,\n createdAt: pendingTx.createdAt as Date,\n creator: pendingTx.creator,\n digest: pendingTx.digest,\n intention: pendingTx.intention,\n sequenceNumber: pendingTx.sequenceNumber,\n payload: pendingTx.payload,\n votes: pendingTx.votes,\n approvalWeight: this.calculateWeightFromVotes(pendingTx.votes),\n msafeAddress: pendingTx.msafeAddress,\n rejectDigest: rejectPending?.digest ?? '',\n rejectPayload: rejectPending?.payload ?? '',\n rejectVotes: rejectPending?.votes ?? [],\n rejectWeight: this.calculateWeightFromVotes(rejectPending?.votes ?? []),\n };\n }\n\n // TODO: Calculate the votes.\n async historyTransaction(pagination?: Pagination) {\n return this.backend.getHistoryTransactions({\n msafeAddress: this.address,\n ...pagination,\n });\n }\n\n async futureIntentions(pagination?: Pagination) {\n return this.backend.getFutureIntentions({ msafeAddress: this.address, ...pagination });\n }\n\n async currentSequenceNumber() {\n return this.backend.getCurrentSequenceNumber(this.address);\n }\n\n async nextSequenceNumber() {\n return this.backend.getNextSequenceNumber(this.address);\n }\n\n async proposeIntention(input: Omit<IProposeIntentionRequest, 'signature' | 'msafeAddress'>) {\n const message = SigningMessageHelper.proposeIntentionMessage({\n msafeAddress: this.address,\n intention: input.intention,\n sn: input.sequenceNumber,\n });\n const signature = await this.wallet.signPersonalMessage({\n messageStr: message,\n });\n\n await this.backend.proposeIntention({\n ...input,\n msafeAddress: this.address,\n signature: signature.signature,\n });\n }\n\n async proposeCoinTransferIntention(intention: CoinTransferIntention) {\n const sn = await this.nextSequenceNumber();\n return this.proposeIntention({\n application: TransactionDefaultApplication,\n txType: TransactionType.Assets,\n txSubType: TransactionSubTypes.assets.coin.send,\n sequenceNumber: sn,\n intention,\n });\n }\n\n async proposeObjectTransferIntention(intention: ObjectTransferIntention) {\n await buildObjectTransferTxb(this.suiClient, intention, this.address);\n const sn = await this.nextSequenceNumber();\n return this.proposeIntention({\n application: TransactionDefaultApplication,\n txType: TransactionType.Assets,\n txSubType: TransactionSubTypes.assets.object.send,\n sequenceNumber: sn,\n intention,\n });\n }\n\n async voteForTransaction(digest: string, payload: string) {\n const payloadBytes = HexToUint8Array(payload);\n const signature = await this.wallet.signTransactionBlock({ transactionBlock: payloadBytes });\n return this.backend.voteForTransaction({\n msafeAddress: this.address,\n digest,\n signature: signature.signature,\n });\n }\n\n // Shortcut for proposing a transaction to be a pending transaction, and add user vote to it.\n // Requires the multi-sig to be empty in pending transaction.\n async proposePendingTransaction(intention: TxIntention) {\n const txb = new TransactionBlock();\n const payload = await txb.build({ client: this.suiClient });\n const digest = await txb.getDigest({ client: this.suiClient });\n const signature = await this.wallet.signTransactionBlock({ transactionBlock: payload });\n return this.backend.proposePendingTransaction({\n msafeAddress: this.address,\n userAddress: await this.userAddress(),\n intention,\n digest,\n signature: signature.signature,\n });\n }\n\n async rejectCurrentTx() {\n const pendingTx = await this.pendingTransaction();\n if (!pendingTx || pendingTx.rejectDigest !== '') {\n throw new Error('Already rejected');\n }\n\n const payloadToReject = pendingTx.payload;\n const rejectTxb = buildRejectTxb(this.address, payloadToReject);\n const digest = await rejectTxb.getDigest({ client: this.suiClient });\n const payload = await rejectTxb.build({ client: this.suiClient });\n const signature = await this.wallet.signTransactionBlock({ transactionBlock: payload });\n return this.backend.rejectCurrentTx({\n msafeAddress: this.address,\n digest,\n signature: signature.signature,\n });\n }\n\n async buildNextIntentionAndAddToPending() {\n return this.backend.buildNextIntentionAndAddToPending({ msafeAddress: this.address });\n }\n\n async skipNextFailedIntention() {\n return this.backend.skipNextFailedIntention({ msafeAddress: this.address });\n }\n\n async simulateIntention(): Promise<SimulationResult> {\n // Todo, move to API\n const txb = new TransactionBlock(); // await buildIntentionTransaction(this.suiClient, intention, this.address);\n txb.setSender(this.address);\n if (!txb.blockData.gasConfig.price) {\n const refGas = await this.suiClient.getReferenceGasPrice();\n txb.setGasPrice(refGas);\n }\n const payload = await txb.build({ client: this.suiClient });\n const dryRunResult = await this.suiClient.dryRunTransactionBlock({ transactionBlock: payload });\n\n const success = dryRunResult.effects.status.status === 'success';\n const errorMsg = dryRunResult.effects.status.error;\n const gasPrice = BigInt(txb.blockData.gasConfig.price as string);\n const { gasUsed } = dryRunResult.effects;\n\n return {\n success,\n errorMsg,\n gasPrice,\n gasUsed,\n dryRunResult,\n };\n }\n\n async executePendingTx(pending: PendingTx, isRejectTx: boolean = false) {\n const votes = isRejectTx ? pending.rejectVotes : pending.votes;\n const payload = isRejectTx ? pending.rejectPayload : pending.payload;\n\n if (this.calculateWeightFromVotes(votes) < this.info.threshold) {\n throw new Error('Not enough signature');\n }\n\n const sortedSigs: SerializedSignature[] = [];\n const gotSigs = new Map(votes.map((vote) => [vote.userAddress, vote.signature]));\n for (let i = 0; i < this.info.owners.length; i++) {\n const owner = this.info.owners[i];\n const signature = gotSigs.get(owner.address);\n if (signature) {\n sortedSigs.push(signature);\n }\n }\n const multiSignature = this.multiSig.combinePartialSignatures(sortedSigs);\n return this.suiClient.executeTransactionBlock({\n transactionBlock: HexToUint8Array(payload),\n signature: multiSignature,\n options: { showEffects: true },\n });\n }\n\n private calculateWeightFromVotes(votes: { userAddress: string }[]) {\n return this.calculateWeight(votes.map((vote) => vote.userAddress));\n }\n\n private calculateWeight(addressList: string[]) {\n let gotWeight = 0;\n\n for (let i = 0; i < addressList.length; i++) {\n const found = this.info.owners.find((owner) => isSameAddress(owner.address, addressList[i]));\n if (found) {\n gotWeight += found.weight;\n }\n }\n return gotWeight;\n }\n\n get address() {\n return this.multiSig.address;\n }\n\n private get backend() {\n return this.globals.backend;\n }\n\n private get wallet() {\n return this.globals.wallet;\n }\n\n private async userAddress() {\n return this.globals.wallet.address();\n }\n\n private get suiClient() {\n return this.globals.suiClient;\n }\n}\n","export function stringToBuffer(s: string) {\n return Buffer.from(s, 'utf-8');\n}\n\nexport function Uint8ArrayToHex(b: Uint8Array): string {\n return `0x${Array.prototype.map.call(b, (x) => `0${x.toString(16)}`.slice(-2)).join('')}`;\n}\n\nexport function HexToUint8Array(hex: string): Uint8Array {\n return Uint8Array.from(Buffer.from(hex.startsWith('0x') ? hex.slice(2) : hex, 'hex'));\n}\n","import { SerializedSignature } from '@mysten/sui.js/cryptography';\nimport { verifyPersonalMessage, verifyTransactionBlock } from '@mysten/sui.js/verify';\n\nimport { stringToBuffer } from '@/utils/buffer';\nimport { Formatter } from '@/utils/format';\n\nexport class SignatureVerifier {\n static async getPublicKeyFromSignature(input: {\n message: Uint8Array;\n messageType: 'TransactionBlock' | 'Personal';\n signature: SerializedSignature;\n }) {\n if (input.messageType === 'TransactionBlock') {\n return verifyTransactionBlock(input.message, input.signature);\n }\n return verifyPersonalMessage(input.message, input.signature);\n }\n\n static async getPublicKeyFromPersonalSignature(input: { messageStr: string; signature: SerializedSignature }) {\n const message = stringToBuffer(input.messageStr);\n return this.getPublicKeyFromSignature({\n message,\n messageType: 'Personal',\n signature: input.signature,\n });\n }\n\n static async verifySignature(input: {\n message: Uint8Array;\n messageType: 'TransactionBlock' | 'Personal';\n signature: SerializedSignature;\n targetAddress: string;\n }) {\n const publicKey = await SignatureVerifier.getPublicKeyFromSignature(input);\n return Formatter.isSuiAddressEqual(publicKey.toSuiAddress(), input.targetAddress);\n }\n\n static async verifyPersonalSignature(input: {\n messageStr: string;\n signature: SerializedSignature;\n targetAddress: string;\n }) {\n const message = stringToBuffer(input.messageStr);\n return this.verifySignature({\n message,\n messageType: 'Personal',\n signature: input.signature,\n targetAddress: input.targetAddress,\n });\n }\n\n static async verifyTransactionSignature(input: {\n payload: Uint8Array;\n signature: SerializedSignature;\n targetAddress: string;\n }): Promise<boolean> {\n return this.verifySignature({\n messageType: 'TransactionBlock',\n message: input.payload,\n signature: input.signature,\n targetAddress: input.targetAddress,\n });\n }\n}\n","import { normalizeSuiAddress, normalizeStructTag } from '@mysten/sui.js/utils';\n\nimport { Coin } from '@/utils/coin';\n\nexport class Formatter {\n static normalizeSuiAddress(addr: string) {\n return normalizeSuiAddress(addr);\n }\n\n static normalizeStructTag(struct: string) {\n return normalizeStructTag(struct);\n }\n\n static isSuiAddressEqual(addr1: string, addr2: string) {\n return normalizeSuiAddress(addr1) === normalizeSuiAddress(addr2);\n }\n\n static isSuiStructEqual(struct1: string, struct2: string) {\n return normalizeStructTag(struct1) === normalizeStructTag(struct2);\n }\n\n static isCoinObjectType(struct: string) {\n return Coin.isCoin(struct);\n }\n}\n","import { CoinMetadata, SuiClient, SuiObjectData } from '@mysten/sui.js/client';\nimport { normalizeStructTag } from '@mysten/sui.js/utils';\n\n// CoinHelper is the coin helper to query for coin metadata.\nexport class CoinHelper {\n private _client: SuiClient;\n\n private _coinMetaReg: Map<string, CoinMetadata>;\n\n constructor(client: SuiClient) {\n this._client = client;\n this._coinMetaReg = new Map();\n }\n\n async getCoinMeta(coinType: string): Promise<CoinMetadata | undefined> {\n const normalized = normalizeStructTag(coinType);\n if (this._coinMetaReg.has(normalized)) {\n return this._coinMetaReg.get(normalized);\n }\n const meta = await this.queryCoinMeta(normalized);\n if (meta) {\n this._coinMetaReg.set(normalized, meta);\n }\n return meta;\n }\n\n private async queryCoinMeta(coinType: string): Promise<CoinMetadata | undefined> {\n const res = await this._client.getCoinMetadata({ coinType });\n return res || undefined;\n }\n}\n\n// Copied from sui/sdk/typescript/src/framework/framework.ts\n\nexport const COIN_TYPE_ARG_REGEX =\n /^0x0000000000000000000000000000000000000000000000000000000000000002::coin::Coin<(.+)>$/;\n\nexport class Coin {\n static isCoin(type: string | undefined | null): boolean {\n if (!type) {\n return false;\n }\n return normalizeStructTag(type).match(COIN_TYPE_ARG_REGEX) != null;\n }\n\n static getCoinType(type: string) {\n const [, res] = normalizeStructTag(type).match(COIN_TYPE_ARG_REGEX) ?? [];\n return res || null;\n }\n\n static getBalance(data: SuiObjectData): bigint | undefined {\n if (!Coin.isCoin(data.type)) {\n return undefined;\n }\n if (data.content?.dataType !== 'moveObject') {\n return undefined;\n }\n const { balance } = data.content?.fields as any;\n if (balance === undefined) {\n return undefined;\n }\n return BigInt(balance);\n }\n}\n","import { PublicKeySerde } from '@msafe/sui3-utils';\nimport { SuiClient, PaginatedTransactionResponse, PaginatedCoins, CoinStruct } from '@mysten/sui.js/client';\nimport { parseSerializedSignature, PublicKey, SerializedSignature } from '@mysten/sui.js/cryptography';\nimport { MultiSigPublicKey } from '@mysten/sui.js/multisig';\n\nimport { Formatter } from '@/utils/format';\n\nexport const SUI_COIN = '0x2::sui::SUI';\n\nexport async function getPublicKeyFromChain(suiClient: SuiClient, address: string): Promise<PublicKey | undefined> {\n let txs: PaginatedTransactionResponse;\n try {\n txs = await suiClient.queryTransactionBlocks({\n // Disable naming rule since the variable is defined by Mysten\n filter: { FromAddress: address },\n options: { showInput: true },\n limit: 2,\n });\n } catch (e) {\n // Currently when there is no history transaction, will report an error:\n // Error: byte deserialization failed, cause by: Odd number of digits\n // TODO: remove the catch logic when sui part is fixed;\n return undefined;\n }\n\n if (txs.data.length === 0 || !txs.data[0].transaction?.txSignatures) {\n return undefined;\n }\n const tx = txs.data[0];\n const signatures = tx.transaction?.txSignatures as string[];\n\n for (let i = 0; i !== signatures.length; i++) {\n const serializedSig = signatures[i];\n const pk = getAddressFromSignatures(serializedSig, address);\n if (!pk) {\n continue;\n }\n return pk;\n }\n return undefined;\n}\n\nfunction getAddressFromSignatures(serializedSig: SerializedSignature, targetAddress: string) {\n const decoded = parseSerializedSignature(serializedSig);\n switch (decoded.signatureScheme) {\n case 'MultiSig': {\n const multiSigAddress = new MultiSigPublicKey(decoded.multisig.multisig_pk).toSuiAddress();\n if (Formatter.isSuiAddressEqual(multiSigAddress, targetAddress)) {\n throw new Error('multi-sig wallet cannot be owner');\n }\n return undefined;\n }\n case 'ZkLogin': {\n if (Formatter.isSuiAddressEqual(decoded.zkLogin.address, targetAddress)) {\n throw new Error('ZkLogin wallet cannot be owner');\n }\n return undefined;\n }\n\n case 'ED25519':\n case 'Secp256k1':\n case 'Secp256r1': {\n const pk = PublicKeySerde.de({ publicKeyEncoded: decoded.publicKey, schema: decoded.signatureScheme });\n if (Formatter.isSuiAddressEqual(pk.toSuiAddress(), targetAddress)) {\n return pk;\n }\n return undefined;\n }\n\n default:\n throw new Error('Unknown schema');\n }\n}\n\nexport async function getAllCoins(input: { suiClient: SuiClient; owner: string; coinType: string | undefined }) {\n let hasNext = true;\n let cursor: string | undefined | null;\n const res: CoinStruct[] = [];\n while (hasNext) {\n const currentPage: PaginatedCoins = await input.suiClient.getCoins({\n owner: input.owner,\n coinType: input.coinType,\n cursor,\n });\n res.push(...currentPage.data);\n hasNext = currentPage.hasNextPage;\n cursor = currentPage.nextCursor;\n }\n return res;\n}\n","import { PagedData, Requester } from './requester';\n\nexport const REQUEST_PAGE_SIZE = 25;\n\nexport interface SuiIterator<T> {\n next: () => Promise<T | undefined>;\n hasNext: () => Promise<boolean>;\n}\n\nexport async function getAllFromIterator<T>(it: SuiIterator<T>): Promise<(T | undefined) | (T | undefined)[]> {\n const res: (T | undefined)[] = [];\n while (await it.hasNext()) {\n const val = await it.next();\n res.push(val);\n }\n if (res && Array.isArray(res[0])) {\n return res.flat(1) as T;\n }\n return res;\n}\n\nexport class PagedIterator<T> implements SuiIterator<(T | undefined)[]> {\n private curPage: PagedData<T> | undefined;\n\n private init: boolean;\n\n constructor(public readonly requester: Requester<T>) {\n this.curPage = undefined;\n this.init = true;\n }\n\n async hasNext(): Promise<boolean> {\n if (this.init) {\n if (!this.curPage) {\n this.curPage = await this.requester.doNextRequest();\n }\n return !!this.curPage.data?.length || this.curPage.hasNext;\n }\n if (!this.curPage) {\n throw new Error('invalid implementation of iterator');\n }\n return this.curPage.hasNext;\n }\n\n async next(): Promise<(T | undefined)[]> {\n if (this.init) {\n this.init = false;\n if (!this.curPage) {\n this.curPage = await this.requester.doNextRequest();\n }\n return this.curPage.data;\n }\n this.curPage = await this.requester.doNextRequest();\n return this.curPage.data;\n }\n}\n\nexport class EntryIterator<T> implements SuiIterator<T> {\n cursor: number;\n\n pager: PagedIterator<T>;\n\n curData: (T | undefined)[];\n\n constructor(public readonly requester: Requester<T>) {\n this.pager = new PagedIterator<T>(requester);\n this.curData = [];\n this.cursor = 0;\n }\n\n async hasNext(): Promise<boolean> {\n if (this.cursor < this.curData.length - 1) {\n return true;\n }\n return this.pager.hasNext();\n }\n\n async next(): Promise<T | undefined> {\n this.cursor += 1;\n while (this.cursor >= this.curData.length) {\n if (!(await this.pager.hasNext())) {\n throw new Error('not more data'); // Shall not happen for legit data source.\n } else {\n this.curData = await this.pager.next();\n this.cursor = 0;\n }\n }\n return this.curData[this.cursor];\n }\n}\n","import { SuiObjectResponse, SuiObjectDataOptions, SuiObjectData, SuiClient } from '@mysten/sui.js/client';\n\nimport { EntryIterator, getAllFromIterator, REQUEST_PAGE_SIZE, SuiIterator } from './iterator';\nimport { PagedData, Requester } from './requester';\n\n// TODO: setup testnet faucet and test this file\n\nexport type ObjectFilter = (objRes: SuiObjectResponse) => boolean;\n\n// OidIter is the iterator to give the list of object ids\nexport type OidIter = SuiIterator<string>;\n\nexport interface BatchObjectOptions {\n filter?: ObjectFilter;\n pageSize?: number;\n objectOptions?: SuiObjectDataOptions;\n}\n\n// getObjectsById get the list of objects by id.\n// Compared with the multiGetObject method defined by SUI, this method will do the pagination\n// for get object requests.\nexport async function getObjectsById(\n provider: SuiClient,\n ids: string[],\n options?: BatchObjectOptions,\n): Promise<(SuiObjectData | undefined)[]> {\n const oidIter = new ListOidIterator(ids);\n const iter = new ObjectBatchIterator(provider, oidIter, options);\n return (await getAllFromIterator(iter)) as (SuiObjectData | undefined)[];\n}\n\n// ListOidIterator is the iterator that iterate through a list of ids.\n// This iterator shall be used when the number requested objects is big\n// which is inappropriate to fit the requested objects into a single\n// request.\nexport class ListOidIterator implements OidIter {\n cursor: number;\n\n constructor(public readonly ids: string[]) {\n this.cursor = -1;\n }\n\n async hasNext(): Promise<boolean> {\n return this.cursor < this.ids.length - 1;\n }\n\n async next(): Promise<string> {\n this.cursor += 1;\n if (this.cursor >= this.ids.length) {\n throw new Error('invalid iterator implementation'); // Shall be unreachable\n }\n return this.ids[this.cursor];\n }\n}\n\nexport class ObjectBatchIterator extends EntryIterator<SuiObjectData> {\n constructor(\n public readonly provider: SuiClient,\n public readonly idIter: OidIter,\n public readonly options?: BatchObjectOptions,\n ) {\n super(new ObjectBatchRequester(provider, idIter, options));\n }\n}\n\n// TODO: Test with customize objects\nexport class ObjectBatchRequester implements Requester<SuiObjectData> {\n filter: ObjectFilter | undefined;\n\n pageSize: number;\n\n objectOptions: SuiObjectDataOptions;\n\n constructor(\n public readonly provider: SuiClient,\n public readonly stringIter: OidIter,\n public options?: BatchObjectOptions,\n ) {\n this.filter = options?.filter;\n this.pageSize = options?.pageSize || REQUEST_PAGE_SIZE;\n this.objectOptions = options?.objectOptions || {\n showType: true,\n showContent: true,\n };\n }\n\n async doNextRequest(): Promise<PagedData<SuiObjectData>> {\n const requestPage: string[] = [];\n while (requestPage.length < this.pageSize) {\n const hasNext = await this.stringIter.hasNext();\n if (!hasNext) {\n break;\n }\n const objId = await this.stringIter.next();\n if (objId) {\n requestPage.push(objId);\n }\n }\n const res: SuiObjectResponse[] = await this.provider.multiGetObjects({\n ids: requestPage,\n options: this.objectOptions,\n });\n let filtered: SuiObjectResponse[];\n if (this.filter) {\n const { filter } = this;\n filtered = res.filter((r: SuiObjectResponse) => filter?.(r));\n } else {\n filtered = res;\n }\n return {\n data: filtered.map((objRes) => objRes.data).filter((data) => data) as SuiObjectData[],\n hasNext: await this.stringIter.hasNext(),\n };\n }\n}\n\nexport async function getAllOwnedObjects(\n provider: SuiClient,\n owner: string,\n options?: BatchObjectOptions,\n): Promise<SuiObjectData[]> {\n const iter = new OwnedObjectIterator(provider, owner, options);\n return (await getAllFromIterator(iter)) as SuiObjectData[];\n}\n\nexport class OwnedObjectIterator extends EntryIterator<SuiObjectData> implements SuiIterator<SuiObjectData> {\n constructor(\n public readonly provider: SuiClient,\n public readonly owner: string,\n public readonly options?: BatchObjectOptions,\n ) {\n super(new OwnedObjectRequester(provider, owner, options));\n }\n}\n\nexport class OwnedObjectRequester implements Requester<SuiObjectData> {\n nextCursor: string | null;\n\n public filter: ObjectFilter | undefined;\n\n public pageSize: number;\n\n public objectOptions: SuiObjectDataOptions;\n\n constructor(\n public readonly provider: SuiClient,\n public readonly owner: string,\n public readonly options?: BatchObjectOptions,\n ) {\n this.nextCursor = null;\n this.filter = options?.filter;\n this.pageSize = options?.pageSize || REQUEST_PAGE_SIZE;\n this.objectOptions = options?.objectOptions || {\n showType: true,\n showContent: true,\n };\n }\n\n async doNextRequest(): Promise<PagedData<SuiObjectData>> {\n const res = await this.provider.getOwnedObjects({\n owner: this.owner,\n options: this.objectOptions,\n cursor: this.nextCursor,\n limit: this.pageSize,\n });\n this.nextCursor = res.nextCursor as string;\n let filtered: SuiObjectResponse[];\n if (this.filter) {\n const { filter } = this;\n filtered = res.data.filter((obj: SuiObjectResponse) => filter?.(obj));\n } else {\n filtered = res.data;\n }\n return {\n data: filtered.map((r: SuiObjectResponse) => r.data).filter((data) => data) as SuiObjectData[],\n hasNext: res.hasNextPage,\n };\n }\n}\n","import { PublicKey } from '@mysten/sui.js/src/cryptography';\n\nimport { MSafeGlobals } from '@/globals/MSafeGlobals';\nimport { getPublicKeyFromChain } from '@/utils/sui';\n\n/**\n * PublicKeyHelper is the helper to query for public keys from\n * backend and blockchain.\n */\nexport class PublicKeyHelper {\n private knownPublicKeys: Map<string, PublicKey>;\n\n constructor(public readonly globals: MSafeGlobals) {\n this.knownPublicKeys = new Map<string, PublicKey>();\n }\n\n async getPublicKey(address: string) {\n const cached = this.knownPublicKeys.get(address);\n if (cached) {\n return cached;\n }\n const pk = await this._getPublicKey(address);\n if (pk) {\n this.knownPublicKeys.set(address, pk);\n }\n return pk;\n }\n\n async getPublicKeyBatch(addresses: string[]): Promise<(PublicKey | undefined)[]> {\n const results: (PublicKey | undefined)[] = new Array(addresses.length).fill(undefined);\n\n // Query local cache first\n for (let i = 0; i < addresses.length; i++) {\n const address = addresses[i];\n results[i] = this.knownPublicKeys.get(address);\n }\n\n // Query backend in batch\n const emptyIndexes = results\n .map((elem, index) => (elem === undefined ? index : -1))\n .filter((index) => index !== -1);\n if (emptyIndexes.length === 0) {\n return results;\n }\n const backendResult = await this.globals.backend.getPublicKeyBatch(emptyIndexes.map((index) => addresses[index]));\n for (let i = 0; i < emptyIndexes.length; i++) {\n const index = emptyIndexes[i];\n results[index] = backendResult[i];\n }\n\n // Query the public key from blockchain\n for (let i = 0; i < results.length; i++) {\n if (results[i] === undefined) {\n results[i] = await this.getPublicKeyFromChain(addresses[i]);\n }\n }\n\n // Finally, write the public keys to the local cache\n for (let i = 0; i < addresses.length; i++) {\n if (results[i]) {\n this.knownPublicKeys.set(addresses[i], results[i] as PublicKey);\n }\n }\n return results;\n }\n\n private async _getPublicKey(address: string) {\n const pkBackend = await this.getPublicKeyFromBackend(address);\n if (pkBackend) {\n return pkBackend;\n }\n const pkChain = await this.getPublicKeyFromChain(address);\n if (pkChain) {\n return pkChain;\n }\n return undefined;\n }\n\n private async getPublicKeyFromBackend(address: string): Promise<PublicKey | undefined> {\n try {\n const pk = await this.globals.backend.getPublicKey(address);\n return pk;\n } catch (_) {\n return undefined;\n }\n }\n\n private async getPublicKeyFromChain(address: string): Promise<PublicKey | undefined> {\n return getPublicKeyFromChain(this.globals.suiClient, address);\n }\n}\n","import { SuiClient } from '@mysten/sui.js/client';\n\nimport { BackendImpl } from '@/backend/BackendImpl';\nimport { IBackend } from '@/backend/interface';\nimport { getMSafeConfig, MSafeConfig, MSafeConfigOptions, MSafeEnv } from '@/globals/const';\nimport { IWallet } from '@/types/wallet';\n\nexport class MSafeGlobals {\n public readonly backend: IBackend;\n\n public readonly suiClient: SuiClient;\n\n public readonly config: MSafeConfig;\n\n _wallet: IWallet | undefined;\n\n constructor(input: { backend: IBackend; suiClient: SuiClient; config: MSafeConfig }) {\n this.backend = input.backend;\n this.suiClient = input.suiClient;\n this.config = input.config;\n }\n\n static async New(env: MSafeEnv, options?: MSafeConfigOptions) {\n const config = getMSafeConfig(env, options);\n const suiClient = new SuiClient(config.suiClient);\n const backend = new BackendImpl(config.backend.url);\n return new MSafeGlobals({\n backend,\n suiClient,\n config,\n });\n }\n\n connectWallet(wallet: IWallet) {\n this._wallet = wallet;\n }\n\n get wallet() {\n if (!this._wallet) {\n throw new Error('wallet not connected');\n }\n return this._wallet;\n }\n\n set wallet(val: IWallet) {\n this._wallet = val;\n }\n}\n","import {\n GetHistoryTransactionsResponse,\n GetPendingTransactionResponse,\n GetTransactionIntentionsResponse,\n IAuthLoginReq,\n IAuthLoginResp,\n IBuildTransactionRequest,\n ICreateMSafeReq,\n IGetAddressBookResult,\n IGetHistoryTransactionsRequest,\n IGetIntentionsRequest,\n IGetMSafeQuery,\n IGetMSafesQuery,\n IGetPendingTransactionRequest,\n IGetPublicKeyBatchQuery,\n IGetPublicKeyBatchResp,\n IMSafeConfig,\n IMSafeInfoResp,\n IPageOptions,\n IPagedResult,\n IProposeIntentionRequest,\n ISkipIntentionRequest,\n IUpdateMSafeStatusReq,\n IUserInfoResp,\n IVoteTransactionRequest,\n JWTToken,\n PublicKeySerde,\n TxIntention,\n UpdateAddressBookEntry,\n UserMSafeStatus,\n} from '@msafe/sui3-utils';\nimport { SerializedSignature } from '@mysten/sui.js/cryptography';\nimport { PublicKey } from '@mysten/sui.js/src/cryptography';\nimport axios from 'axios';\n\nimport { IBackend } from '@/backend/interface';\n\nexport class BackendImpl implements IBackend {\n private _token: JWTToken;\n\n constructor(private readonly apiURL: string) {}\n\n async authSign(input: IAuthLoginReq): Promise<JWTToken> {\n const res = await axios.post<IAuthLoginResp>(`${this.apiURL}/auth/login`, input);\n // TODO unify response struct\n if (res.status !== 200 && res.status !== 201) {\n throw new Error(`invalid authSign return: ${res}`);\n }\n this._token = res.data.accessToken;\n return this._token;\n }\n\n async verifyToken(jwt: JWTToken): Promise<boolean> {\n try {\n const res = await axios.get(`${this.apiURL}/auth`, { headers: this.headers(jwt) });\n return res.status === 200;\n } catch (_) {\n return false;\n }\n }\n\n setJWTToken(token: JWTToken) {\n this._token = token;\n }\n\n async getPublicKey(address: string): Promise<PublicKey | undefined> {\n return (await this.getPublicKeyBatch([address]))[0];\n }\n\n async getPublicKeyBatch(addresses: string[]): Promise<(PublicKey | undefined)[]> {\n const query: IGetPublicKeyBatchQuery = {\n userAddressList: addresses,\n };\n const res = await axios.get<IGetPublicKeyBatchResp>(`${this.apiURL}/user/public-keys`, {\n params: query,\n headers: this.headers(),\n });\n\n // TODO unify response struct\n if (res.status !== 200 && res.status !== 201) {\n throw new Error(`invalid getPublicKeyBatch return: ${res}`);\n }\n return res.data?.map((publicKeyWithSchema) =>\n publicKeyWithSchema ? PublicKeySerde.de(publicKeyWithSchema) : undefined,\n );\n }\n\n async getMSafeAccountInfo(msafeAddress: string): Promise<IMSafeConfig> {\n const q: IGetMSafeQuery = {\n msafeAddress,\n };\n const res = await axios.get<IMSafeInfoResp>(`${this.apiURL}/msafe`, {\n params: q,\n headers: this.headers(),\n });\n // TODO unify response struct\n if (res.status !== 200 && res.status !== 201) {\n throw new Error(`invalid getPublicKeyBatch return: ${res}`);\n }\n return BackendImpl.toMSafeConfig(res.data);\n }\n\n async getUserInfo(): Promise<IUserInfoResp> {\n const userRes = await axios.get<IUserInfoResp>(`${this.apiURL}/user`, {\n headers: this.headers(),\n });\n // TODO unify response struct\n if (userRes.status !== 200 && userRes.status !== 201) {\n throw new Error(`invalid getPublicKeyBatch return: ${userRes}`);\n }\n return userRes.data;\n }\n\n async getOwnedMSafeByStatus(input: {\n status?: UserMSafeStatus;\n pagination?: IPageOptions;\n }): Promise<IPagedResult<IMSafeConfig>> {\n const q: IGetMSafesQuery = {\n status: input.status ?? UserMSafeStatus.active,\n ...(input.pagination\n ? {\n page: input.pagination.page.toString(),\n limit: input.pagination.limit.toString(),\n }\n : {}),\n };\n const res = await axios.get<IPagedResult<IMSafeInfoResp>>(`${this.apiURL}/msafe/owned`, {\n params: q,\n headers: this.headers(),\n });\n if (res.status !== 200 && res.status !== 201) {\n throw new Error(`invalid getOwnedMSafeByStatus return: ${res}`);\n }\n return {\n data: res.data.data.map(BackendImpl.toMSafeConfig),\n meta: res.data.meta,\n };\n }\n\n async updateMSafeStatus(input: { msafeAddress: string; status: UserMSafeStatus }): Promise<void> {\n const p: IUpdateMSafeStatusReq = input;\n const res = await axios.post(`${this.apiURL}/msafe/status`, p, { headers: this.headers() });\n if (res.status !== 200 && res.status !== 201) {\n throw new Error(`Invalid updateMSafeStatus return: ${res}`);\n }\n }\n\n async getPendingTransactions(input: IGetPendingTransactionRequest): Promise<GetPendingTransactionResponse> {\n const res = await axios.get<GetPendingTransactionResponse>(`${this.apiURL}/transaction/pending`, {\n params: input,\n headers: this.headers(),\n });\n if (res.status !== 200 && res.status !== 201) {\n throw new Error(`invalid getPublicKeyBatch return: ${res}`);\n }\n return res.data;\n }\n\n async getHistoryTransactions(input: IGetHistoryTransactionsRequest): Promise<GetHistoryTransactionsResponse> {\n const res = await axios.get<GetHistoryTransactionsResponse>(`${this.apiURL}/transaction/history`, {\n params: input,\n headers: this.headers(),\n });\n if (res.status !== 200 && res.status !== 201) {\n throw new Error(`invalid getCurrentSequenceNumber return: ${res}`);\n }\n return res.data;\n }\n\n async getFutureIntentions(input: IGetIntentionsRequest): Promise<GetTransactionIntentionsResponse> {\n const res = await axios.get<GetTransactionIntentionsResponse>(`${this.apiURL}/transaction/intention`, {\n params: input,\n headers: this.headers(),\n });\n if (res.status !== 200 && res.status !== 201) {\n throw new Error(`invalid getCurrentSequenceNumber return: ${res}`);\n }\n return res.data;\n }\n\n async getCurrentSequenceNumber(address: string): Promise<number> {\n const res = await axios.get<number>(`${this.apiURL}/transaction/sn/current`, {\n params: {\n msafeAddress: address,\n },\n headers: this.headers(),\n });\n if (res.status !== 200 && res.status !== 201) {\n throw new Error(`invalid getCurrentSequenceNumber return: ${res}`);\n }\n return res.data;\n }\n\n async getNextSequenceNumber(address: string): Promise<number> {\n const res = await axios.get<number>(`${this.apiURL}/transaction/sn/next`, {\n params: {\n msafeAddress: address,\n },\n headers: this.headers(),\n });\n if (res.status !== 200 && res.status !== 201) {\n throw new Error(`invalid getNextSequenceNumber return: ${res}`);\n }\n return res.data;\n }\n\n async createMSafeAccount(input: ICreateMSafeReq): Promise<void> {\n const res = await axios.post(`${this.apiURL}/msafe/create`, input, {\n headers: this.headers(),\n });\n if (res.status !== 200 && res.status !== 201) {\n throw new Error(`invalid createMSafeAccount return: ${res}`);\n }\n }\n\n async proposeIntention(input: IProposeIntentionRequest): Promise<void> {\n const res = await axios.post(`${this.apiURL}/transaction/intention`, input, { headers: this.headers() });\n if (res.status !== 200 && res.status !== 201) {\n throw new Error(`invalid proposeIntention return: ${res}`);\n }\n }\n\n // TODO later\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n async proposePendingTransaction(_input: {\n intention: TxIntention;\n userAddress: string;\n msafeAddress: string;\n digest: string;\n signature: SerializedSignature;\n }): Promise<void> {\n return undefined;\n }\n\n async rejectCurrentTx(input: IVoteTransactionRequest) {\n const res = await axios.post(`${this.apiURL}/transaction/pending/reject`, input, {\n headers: this.headers(),\n });\n if (res.status !== 200 && res.status !== 201) {\n throw new Error(`invalid voteForTransaction return: ${res}`);\n }\n }\n\n async voteForTransaction(input: IVoteTransactionRequest) {\n const res = await axios.post(`${this.apiURL}/transaction/pending/vote`, input, {\n headers: this.headers(),\n });\n if (res.status !== 200 && res.status !== 201) {\n throw new Error(`invalid voteForTransaction return: ${res}`);\n }\n }\n\n async buildNextIntentionAndAddToPending(input: IBuildTransactionRequest) {\n const res = await axios.post(`${this.apiURL}/transaction/pending/build`, input, { headers: this.headers() });\n if (res.status !== 200 && res.status !== 201) {\n throw new Error(`invalid buildNextIntentionAndAddToPending return: ${res}`);\n }\n }\n\n async skipNextFailedIntention(input: ISkipIntentionRequest) {\n const res = await axios.post(`${this.apiURL}/transaction/pending/skip`, input, { headers: this.headers() });\n if (res.status !== 200 && res.status !== 201) {\n throw new Error(`invalid skipNextFailedIntention return: ${res}`);\n }\n }\n\n async getAddressBookEntries(pagination?: IPageOptions): Promise<IGetAddressBookResult> {\n const res = await axios.get<IGetAddressBookResult>(`${this.apiURL}/address-book`, {\n headers: this.headers(),\n params: pagination,\n });\n if (res.status !== 200) {\n throw new Error(`Invalid address-book return: ${res}`);\n }\n return res.data;\n }\n\n async updateAddressBook(input: { updates: UpdateAddressBookEntry[]; signature: SerializedSignature }) {\n const res = await axios.post(`${this.apiURL}/address-book`, input, { headers: this.headers() });\n if (res.status !== 200 && res.status !== 201) {\n throw new Error(`invalid updateAddressBook return: ${res}`);\n }\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n async processExecutedTransaction(_digest: string) {\n return undefined;\n }\n\n private headers(token?: string) {\n return { Authorization: `Bearer ${token || this._token}` };\n }\n\n private static toMSafeConfig(resp: IMSafeInfoResp): IMSafeConfig {\n return {\n ...resp,\n owners: resp.owners.map((owner) => ({\n address: owner.address,\n weight: owner.weight,\n publicKey: PublicKeySerde.de({\n publicKeyEncoded: owner.publicKeyEncoded,\n schema: owner.schema,\n }),\n })),\n };\n }\n}\n","export enum MSafeEnv {\n local = 'local',\n unit = 'unit',\n dev = 'dev',\n prev = 'prev',\n prod = 'prod',\n}\n\nexport interface MSafeConfig {\n suiClient: {\n url: string;\n };\n backend: {\n url: string;\n };\n syncingURL: string;\n}\n\nexport interface MSafeConfigOptions {\n suiClient?: {\n url?: string;\n };\n backend?: {\n url?: string;\n };\n}\nexport const MSAFE_APPLICATION = 'msafe';\n\nexport const TESTNET_RPC_URL = 'https://sui-testnet.blockvision.org/v1/2Sgk89ivT64MnKdcGzjmyjY2ndD';\nexport const MAINNET_RPC_URL = 'https://sui-mainnet.blockvision.org/v1/2Sgk7NPvqkd7mESYkxF01yX15l7';\n\nexport const LOCAL_API_URL = 'http://127.0.0.1:3000';\nexport const LOCAL_SYNCING_URL = 'http://127.0.0.1:3001';\n\nexport const DEV_API_URL = 'http://13.56.226.148';\nexport const DEV_SYNCING_URL = 'http://52.53.228.20';\n\nexport const ENV_CONFIGS = new Map<MSafeEnv, MSafeConfig>([\n [\n MSafeEnv.unit,\n {\n suiClient: {\n url: TESTNET_RPC_URL,\n },\n backend: {\n url: LOCAL_API_URL,\n },\n syncingURL: LOCAL_SYNCING_URL,\n },\n ],\n [\n MSafeEnv.local,\n {\n suiClient: {\n url: TESTNET_RPC_URL,\n },\n backend: {\n url: LOCAL_API_URL,\n },\n syncingURL: LOCAL_SYNCING_URL,\n },\n ],\n [\n MSafeEnv.dev,\n {\n suiClient: {\n url: TESTNET_RPC_URL,\n },\n backend: {\n url: DEV_API_URL,\n },\n syncingURL: DEV_SYNCING_URL,\n },\n ],\n]);\n\nexport function getMSafeConfig(env: MSafeEnv, options?: MSafeConfigOptions) {\n const config = ENV_CONFIGS.get(env);\n if (!config) {\n throw new Error('Unknown environment');\n }\n if (options?.suiClient?.url) {\n config.suiClient.url = options.suiClient.url;\n }\n if (options?.backend?.url) {\n config.backend.url = options.backend.url;\n }\n return config;\n}\n"],"mappings":"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","names":["import_sui3_utils","import_sui3_utils","import_sui3_utils","import_utils","import_utils","import_sui3_utils","import_sui3_utils","axios","MSafeEnv"]}
package/dist/index.d.cts CHANGED
@@ -142,9 +142,11 @@ interface PendingTx {
142
142
  creator: string;
143
143
  createdAt: Date;
144
144
  sequenceNumber: number;
145
+ approvalWeight: number;
145
146
  votes: PendingVote[];
146
147
  rejectDigest: string;
147
148
  rejectPayload: string;
149
+ rejectWeight: number;
148
150
  rejectVotes: PendingVote[];
149
151
  }
150
152
  interface PendingVote {
@@ -283,7 +285,9 @@ declare class MSafeAccount {
283
285
  buildNextIntentionAndAddToPending(): Promise<void>;
284
286
  skipNextFailedIntention(): Promise<void>;
285
287
  simulateIntention(): Promise<SimulationResult>;
286
- executePendingTx(pending: PendingTx): Promise<_mysten_sui_js_client.SuiTransactionBlockResponse>;
288
+ executePendingTx(pending: PendingTx, isRejectTx?: boolean): Promise<_mysten_sui_js_client.SuiTransactionBlockResponse>;
289
+ private calculateWeightFromVotes;
290
+ private calculateWeight;
287
291
  get address(): string;
288
292
  private get backend();
289
293
  private get wallet();
package/dist/index.d.ts CHANGED
@@ -142,9 +142,11 @@ interface PendingTx {
142
142
  creator: string;
143
143
  createdAt: Date;
144
144
  sequenceNumber: number;
145
+ approvalWeight: number;
145
146
  votes: PendingVote[];
146
147
  rejectDigest: string;
147
148
  rejectPayload: string;
149
+ rejectWeight: number;
148
150
  rejectVotes: PendingVote[];
149
151
  }
150
152
  interface PendingVote {
@@ -283,7 +285,9 @@ declare class MSafeAccount {
283
285
  buildNextIntentionAndAddToPending(): Promise<void>;
284
286
  skipNextFailedIntention(): Promise<void>;
285
287
  simulateIntention(): Promise<SimulationResult>;
286
- executePendingTx(pending: PendingTx): Promise<_mysten_sui_js_client.SuiTransactionBlockResponse>;
288
+ executePendingTx(pending: PendingTx, isRejectTx?: boolean): Promise<_mysten_sui_js_client.SuiTransactionBlockResponse>;
289
+ private calculateWeightFromVotes;
290
+ private calculateWeight;
287
291
  get address(): string;
288
292
  private get backend();
289
293
  private get wallet();
package/dist/index.js CHANGED
@@ -102,7 +102,8 @@ import {
102
102
  TransactionSubTypes,
103
103
  TransactionType,
104
104
  buildObjectTransferTxb,
105
- buildRejectTxb
105
+ buildRejectTxb,
106
+ isSameAddress
106
107
  } from "@msafe/sui3-utils";
107
108
  import { TransactionBlock } from "@mysten/sui.js/transactions";
108
109
  import { normalizeStructTag as normalizeStructTag3 } from "@mysten/sui.js/utils";
@@ -481,6 +482,7 @@ var MSafeAccount = class _MSafeAccount {
481
482
  };
482
483
  return getAllOwnedObjects(this.suiClient, this.address, filterCoinObjectOptions);
483
484
  }
485
+ // TODO: Calculate the votes
484
486
  async pendingTransaction() {
485
487
  const res = await this.backend.getPendingTransactions({ msafeAddress: this.address });
486
488
  if (!res.pending) {
@@ -498,12 +500,15 @@ var MSafeAccount = class _MSafeAccount {
498
500
  sequenceNumber: pendingTx.sequenceNumber,
499
501
  payload: pendingTx.payload,
500
502
  votes: pendingTx.votes,
503
+ approvalWeight: this.calculateWeightFromVotes(pendingTx.votes),
501
504
  msafeAddress: pendingTx.msafeAddress,
502
505
  rejectDigest: rejectPending?.digest ?? "",
503
506
  rejectPayload: rejectPending?.payload ?? "",
504
- rejectVotes: rejectPending?.votes ?? []
507
+ rejectVotes: rejectPending?.votes ?? [],
508
+ rejectWeight: this.calculateWeightFromVotes(rejectPending?.votes ?? [])
505
509
  };
506
510
  }
511
+ // TODO: Calculate the votes.
507
512
  async historyTransaction(pagination) {
508
513
  return this.backend.getHistoryTransactions({
509
514
  msafeAddress: this.address,
@@ -622,33 +627,41 @@ var MSafeAccount = class _MSafeAccount {
622
627
  dryRunResult
623
628
  };
624
629
  }
625
- async executePendingTx(pending) {
626
- let gotSigs;
627
- let payload;
628
- if (pending.votes.length >= this.info.threshold) {
629
- gotSigs = new Map(pending.votes.map((vote) => [vote.userAddress, vote.signature]));
630
- payload = pending.payload;
631
- } else if (pending.rejectVotes && pending.rejectPayload && pending.rejectVotes?.length >= this.info.threshold) {
632
- gotSigs = new Map(pending.rejectVotes.map((vote) => [vote.userAddress, vote.signature]));
633
- payload = pending.rejectPayload;
634
- } else {
635
- throw new Error("Not enough signatures");
630
+ async executePendingTx(pending, isRejectTx = false) {
631
+ const votes = isRejectTx ? pending.rejectVotes : pending.votes;
632
+ const payload = isRejectTx ? pending.rejectPayload : pending.payload;
633
+ if (this.calculateWeightFromVotes(votes) < this.info.threshold) {
634
+ throw new Error("Not enough signature");
636
635
  }
637
- const sigs = [];
636
+ const sortedSigs = [];
637
+ const gotSigs = new Map(votes.map((vote) => [vote.userAddress, vote.signature]));
638
638
  for (let i = 0; i < this.info.owners.length; i++) {
639
639
  const owner = this.info.owners[i];
640
640
  const signature = gotSigs.get(owner.address);
641
641
  if (signature) {
642
- sigs.push(signature);
642
+ sortedSigs.push(signature);
643
643
  }
644
644
  }
645
- const multiSignature = this.multiSig.combinePartialSignatures(sigs);
645
+ const multiSignature = this.multiSig.combinePartialSignatures(sortedSigs);
646
646
  return this.suiClient.executeTransactionBlock({
647
647
  transactionBlock: HexToUint8Array(payload),
648
648
  signature: multiSignature,
649
649
  options: { showEffects: true }
650
650
  });
651
651
  }
652
+ calculateWeightFromVotes(votes) {
653
+ return this.calculateWeight(votes.map((vote) => vote.userAddress));
654
+ }
655
+ calculateWeight(addressList) {
656
+ let gotWeight = 0;
657
+ for (let i = 0; i < addressList.length; i++) {
658
+ const found = this.info.owners.find((owner) => isSameAddress(owner.address, addressList[i]));
659
+ if (found) {
660
+ gotWeight += found.weight;
661
+ }
662
+ }
663
+ return gotWeight;
664
+ }
652
665
  get address() {
653
666
  return this.multiSig.address;
654
667
  }
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/core/CreateHelper.ts","../src/core/MSafeClient.ts","../src/core/AddressBookSDK.ts","../src/core/InvitationSDK.ts","../src/core/MSafeAccount.ts","../src/utils/buffer.ts","../src/utils/crypto.ts","../src/utils/format.ts","../src/utils/coin.ts","../src/utils/sui.ts","../src/utils/iter/iterator.ts","../src/utils/iter/object.ts","../src/core/PublicKeyHelper.ts","../src/globals/MSafeGlobals.ts","../src/backend/BackendImpl.ts","../src/globals/const.ts"],"sourcesContent":["import { MultiSigAccount, MultiSigConfig, PublicKeySerde, SigningMessageHelper } from '@msafe/sui3-utils';\nimport { PublicKey, SerializedSignature } from '@mysten/sui.js/cryptography';\n\nimport { PublicKeyHelper } from '@/core/PublicKeyHelper';\nimport { MSafeGlobals } from '@/globals/MSafeGlobals';\nimport { CreateMSafeInfo } from '@/types';\n\nexport class CreateHelper {\n constructor(\n public readonly globals: MSafeGlobals,\n public readonly pkHelper: PublicKeyHelper,\n ) {}\n\n async getPublicKeyBatch(addresses: string[]) {\n return this.pkHelper.getPublicKeyBatch(addresses);\n }\n\n async calculateMSafeAddress(info: CreateMSafeInfo) {\n const msConfig = await this.reduceCreationInfoToRawConfig(info);\n const ms = new MultiSigAccount(msConfig);\n return ms.address;\n }\n\n // Validate the create info and return the msafe address.\n async validateCreateInfo(createInfo: CreateMSafeInfo) {\n // Calculate the sui address will check the multi-sig\n return this.calculateMSafeAddress(createInfo);\n }\n\n async submitMSafeCreation(creationInfo: CreateMSafeInfo) {\n const msafeAddress = await this.validateCreateInfo(creationInfo);\n\n const signingMessage = SigningMessageHelper.createMSafeMessage(msafeAddress);\n const signature = await this.globals.wallet.signPersonalMessage({ messageStr: signingMessage });\n\n await this.submitToBackend(creationInfo, signature.signature);\n return msafeAddress;\n }\n\n private async reduceCreationInfoToRawConfig(info: CreateMSafeInfo): Promise<MultiSigConfig> {\n const publicKeys = await this.getPublicKeyBatch(info.owners.map((owner) => owner.address));\n publicKeys.forEach((pk, i) => {\n if (pk === undefined) {\n throw new Error(`Unknown public key for address: ${info.owners[i].address}`);\n }\n });\n return {\n threshold: info.threshold,\n ownersWithWeight: info.owners.map((owner, i) => ({\n publicKey: publicKeys[i] as PublicKey,\n weight: owner.weight,\n })),\n creationNonce: info.creationNonce,\n };\n }\n\n private async submitToBackend(createInfo: CreateMSafeInfo, signature: SerializedSignature) {\n const pks = await this.pkHelper.getPublicKeyBatch(createInfo.owners.map((owner) => owner.address));\n await this.globals.backend.createMSafeAccount({\n owners: createInfo.owners.map((owner, i) => ({\n address: owner.address,\n weight: owner.weight,\n ...PublicKeySerde.ser(pks[i] as PublicKey),\n })),\n threshold: createInfo.threshold,\n name: createInfo.name, // name validation is deferred to backend\n description: createInfo.description, // description validation is deferred to backend\n creationNonce: createInfo.creationNonce,\n signature,\n });\n }\n}\n","import {\n IMSafeConfig,\n IPagedResult,\n IPageOptions,\n JWTToken,\n SigningMessageHelper,\n UserMSafeStatus,\n} from '@msafe/sui3-utils';\n\nimport { AddressBookSDK } from '@/core/AddressBookSDK';\nimport { CreateHelper } from '@/core/CreateHelper';\nimport { InvitationSDK } from '@/core/InvitationSDK';\nimport { MSafeAccount } from '@/core/MSafeAccount';\nimport { PublicKeyHelper } from '@/core/PublicKeyHelper';\nimport { MSafeConfigOptions, MSafeEnv } from '@/globals/const';\nimport { MSafeGlobals } from '@/globals/MSafeGlobals';\nimport { CreateMSafeInfo } from '@/types';\nimport { IWallet } from '@/types/wallet';\n\nexport class MSafeClient {\n private _creationHelper: CreateHelper | undefined;\n\n private _publicKeyHelper: PublicKeyHelper | undefined;\n\n constructor(public readonly globals: MSafeGlobals) {}\n\n static async New(env: MSafeEnv, options?: MSafeConfigOptions) {\n const globals = await MSafeGlobals.New(env, options);\n return new MSafeClient(globals);\n }\n\n async connectWallet(input: { wallet: IWallet; jwtToken?: JWTToken }): Promise<JWTToken> {\n if (input.jwtToken) {\n const verified = await this.backend.verifyToken(input.jwtToken);\n if (verified) {\n this.globals.wallet = input.wallet;\n this.backend.setJWTToken(input.jwtToken);\n return input.jwtToken;\n }\n }\n const jwt = await this.authSign(input.wallet);\n this.globals.wallet = input.wallet;\n this.backend.setJWTToken(jwt);\n return jwt;\n }\n\n private async authSign(wallet: IWallet): Promise<JWTToken> {\n const messageStr = SigningMessageHelper.loginMessageWithTimestamp(new Date().toUTCString());\n const sig = await wallet.signPersonalMessage({\n messageStr,\n });\n return this.backend.authSign({\n address: await wallet.address(),\n message: messageStr,\n signature: sig.signature,\n walletType: wallet.walletType,\n });\n }\n\n async userInfo() {\n return this.globals.backend.getUserInfo();\n }\n\n async ownedMSafe(pagination?: IPageOptions): Promise<IPagedResult<IMSafeConfig>> {\n return this.globals.backend.getOwnedMSafeByStatus({ status: UserMSafeStatus.active, pagination });\n }\n\n async createAccount(info: CreateMSafeInfo) {\n return this.creationHelper.submitMSafeCreation(info);\n }\n\n getMSafeAccount(info: IMSafeConfig) {\n return new MSafeAccount(this.globals, info);\n }\n\n async getMSafeAccountFromAddress(msafeAddress: string) {\n const info = await this.backend.getMSafeAccountInfo(msafeAddress);\n return new MSafeAccount(this.globals, info);\n }\n\n // Get the creation helper to calculate the msafe account address,\n // validation, and more.\n get creationHelper() {\n if (!this._creationHelper) {\n this._creationHelper = new CreateHelper(this.globals, this.publicKeyHelper);\n }\n return this._creationHelper;\n }\n\n get publicKeyHelper() {\n if (!this._publicKeyHelper) {\n this._publicKeyHelper = new PublicKeyHelper(this.globals);\n }\n return this._publicKeyHelper;\n }\n\n get config() {\n return this.globals.config;\n }\n\n get backend() {\n return this.globals.backend;\n }\n\n get wallet() {\n return this.globals.wallet;\n }\n\n get AddressBook(): AddressBookSDK {\n return new AddressBookSDK(this.globals);\n }\n\n get Invitation(): InvitationSDK {\n return new InvitationSDK(this.globals);\n }\n\n private async walletAddress() {\n return this.wallet.address();\n }\n}\n","import { IPageOptions, SigningMessageHelper, UpdateAddressBookEntry } from '@msafe/sui3-utils';\n\nimport { MSafeGlobals } from '@/globals';\n\nexport class AddressBookSDK {\n constructor(public readonly globals: MSafeGlobals) {}\n\n async getEntries(pagination?: IPageOptions) {\n return this.globals.backend.getAddressBookEntries(pagination);\n }\n\n async update(updates: UpdateAddressBookEntry[]) {\n const messageStr = SigningMessageHelper.updateAddressBookMessage(updates);\n const sig = await this.globals.wallet.signPersonalMessage({ messageStr });\n return this.globals.backend.updateAddressBook({ updates, signature: sig.signature });\n }\n}\n","import { IMSafeConfig, IPagedResult, IPageOptions, UserMSafeStatus } from '@msafe/sui3-utils';\n\nimport { MSafeGlobals } from '@/globals';\n\nexport class InvitationSDK {\n constructor(public readonly globals: MSafeGlobals) {}\n\n async getMSafeByStatus(status: UserMSafeStatus, pagination?: IPageOptions): Promise<IPagedResult<IMSafeConfig>> {\n return this.globals.backend.getOwnedMSafeByStatus({ status, pagination });\n }\n\n async updateMSafeStatus(msafeAddress: string, status: UserMSafeStatus) {\n return this.globals.backend.updateMSafeStatus({ msafeAddress, status });\n }\n}\n","import {\n CoinTransferIntention,\n IMSafeConfig,\n IProposeIntentionRequest,\n MultiSigAccount,\n ObjectTransferIntention,\n SigningMessageHelper,\n TransactionDefaultApplication,\n TransactionSubTypes,\n TransactionType,\n TxIntention,\n buildObjectTransferTxb,\n buildRejectTxb,\n} from '@msafe/sui3-utils';\nimport { SuiObjectData } from '@mysten/sui.js/client';\nimport { SerializedSignature } from '@mysten/sui.js/cryptography';\nimport { SuiObjectResponse } from '@mysten/sui.js/src/client';\nimport { TransactionBlock } from '@mysten/sui.js/transactions';\nimport { normalizeStructTag } from '@mysten/sui.js/utils';\n\nimport { MSafeGlobals } from '@/globals/MSafeGlobals';\nimport { OwnedCoin } from '@/types/assets';\nimport { Pagination, PendingTx, SimulationResult } from '@/types/msafe';\nimport { CoinHelper } from '@/utils';\nimport { HexToUint8Array } from '@/utils/buffer';\nimport { BatchObjectOptions, getAllOwnedObjects } from '@/utils/iter/object';\n\nexport class MSafeAccount {\n public multiSig: MultiSigAccount;\n\n private coinHelper: CoinHelper;\n\n constructor(\n public readonly globals: MSafeGlobals,\n public readonly info: IMSafeConfig,\n ) {\n this.multiSig = new MultiSigAccount({\n threshold: info.threshold,\n ownersWithWeight: info.owners,\n creationNonce: info.creationNonce,\n });\n this.coinHelper = new CoinHelper(this.suiClient);\n }\n\n static async New(globals: MSafeGlobals, address: string) {\n const info = await globals.backend.getMSafeAccountInfo(address);\n const ms = new MSafeAccount(globals, info);\n if (ms.address !== address) {\n throw new Error('Invalid msafe config with address');\n }\n }\n\n async ownedCoins(): Promise<OwnedCoin[]> {\n const balances = await this.suiClient.getAllBalances({ owner: this.address });\n return Promise.all(\n balances.map(async (balance): Promise<OwnedCoin> => {\n const meta = await this.coinHelper.getCoinMeta(balance.coinType);\n const unlockedBalance = balance.lockedBalance.number\n ? BigInt(balance.totalBalance) - BigInt(balance.lockedBalance.number)\n : BigInt(balance.totalBalance);\n\n return {\n type: normalizeStructTag(balance.coinType),\n balance: BigInt(unlockedBalance),\n metadata: meta,\n };\n }),\n );\n }\n\n async ownedObjects(options?: BatchObjectOptions): Promise<SuiObjectData[]> {\n const filterCoinObjectOptions = {\n filter: (objRes: SuiObjectResponse) => !objRes?.data?.type?.startsWith('0x2::coin::Coin'),\n ...options,\n };\n return getAllOwnedObjects(this.suiClient, this.address, filterCoinObjectOptions);\n }\n\n async pendingTransaction(): Promise<PendingTx | undefined> {\n const res = await this.backend.getPendingTransactions({ msafeAddress: this.address });\n if (!res.pending) {\n return undefined;\n }\n\n const pendingTx = res.pending;\n const rejectPending = res.reject;\n\n return {\n txType: TransactionType.Assets,\n txSubType:\n 'coinType' in pendingTx.intention\n ? TransactionSubTypes.assets.coin.send\n : TransactionSubTypes.assets.object.send,\n createdAt: pendingTx.createdAt as Date,\n creator: pendingTx.creator,\n digest: pendingTx.digest,\n intention: pendingTx.intention,\n sequenceNumber: pendingTx.sequenceNumber,\n payload: pendingTx.payload,\n votes: pendingTx.votes,\n msafeAddress: pendingTx.msafeAddress,\n rejectDigest: rejectPending?.digest ?? '',\n rejectPayload: rejectPending?.payload ?? '',\n rejectVotes: rejectPending?.votes ?? [],\n };\n }\n\n async historyTransaction(pagination?: Pagination) {\n return this.backend.getHistoryTransactions({\n msafeAddress: this.address,\n ...pagination,\n });\n }\n\n async futureIntentions(pagination?: Pagination) {\n return this.backend.getFutureIntentions({ msafeAddress: this.address, ...pagination });\n }\n\n async currentSequenceNumber() {\n return this.backend.getCurrentSequenceNumber(this.address);\n }\n\n async nextSequenceNumber() {\n return this.backend.getNextSequenceNumber(this.address);\n }\n\n async proposeIntention(input: Omit<IProposeIntentionRequest, 'signature' | 'msafeAddress'>) {\n const message = SigningMessageHelper.proposeIntentionMessage({\n msafeAddress: this.address,\n intention: input.intention,\n sn: input.sequenceNumber,\n });\n const signature = await this.wallet.signPersonalMessage({\n messageStr: message,\n });\n\n await this.backend.proposeIntention({\n ...input,\n msafeAddress: this.address,\n signature: signature.signature,\n });\n }\n\n async proposeCoinTransferIntention(intention: CoinTransferIntention) {\n const sn = await this.nextSequenceNumber();\n return this.proposeIntention({\n application: TransactionDefaultApplication,\n txType: TransactionType.Assets,\n txSubType: TransactionSubTypes.assets.coin.send,\n sequenceNumber: sn,\n intention,\n });\n }\n\n async proposeObjectTransferIntention(intention: ObjectTransferIntention) {\n await buildObjectTransferTxb(this.suiClient, intention, this.address);\n const sn = await this.nextSequenceNumber();\n return this.proposeIntention({\n application: TransactionDefaultApplication,\n txType: TransactionType.Assets,\n txSubType: TransactionSubTypes.assets.object.send,\n sequenceNumber: sn,\n intention,\n });\n }\n\n async voteForTransaction(digest: string, payload: string) {\n const payloadBytes = HexToUint8Array(payload);\n const signature = await this.wallet.signTransactionBlock({ transactionBlock: payloadBytes });\n return this.backend.voteForTransaction({\n msafeAddress: this.address,\n digest,\n signature: signature.signature,\n });\n }\n\n // Shortcut for proposing a transaction to be a pending transaction, and add user vote to it.\n // Requires the multi-sig to be empty in pending transaction.\n async proposePendingTransaction(intention: TxIntention) {\n const txb = new TransactionBlock();\n const payload = await txb.build({ client: this.suiClient });\n const digest = await txb.getDigest({ client: this.suiClient });\n const signature = await this.wallet.signTransactionBlock({ transactionBlock: payload });\n return this.backend.proposePendingTransaction({\n msafeAddress: this.address,\n userAddress: await this.userAddress(),\n intention,\n digest,\n signature: signature.signature,\n });\n }\n\n async rejectCurrentTx() {\n const pendingTx = await this.pendingTransaction();\n if (!pendingTx || pendingTx.rejectDigest !== '') {\n throw new Error('Already rejected');\n }\n\n const payloadToReject = pendingTx.payload;\n const rejectTxb = buildRejectTxb(this.address, payloadToReject);\n const digest = await rejectTxb.getDigest({ client: this.suiClient });\n const payload = await rejectTxb.build({ client: this.suiClient });\n const signature = await this.wallet.signTransactionBlock({ transactionBlock: payload });\n return this.backend.rejectCurrentTx({\n msafeAddress: this.address,\n digest,\n signature: signature.signature,\n });\n }\n\n async buildNextIntentionAndAddToPending() {\n return this.backend.buildNextIntentionAndAddToPending({ msafeAddress: this.address });\n }\n\n async skipNextFailedIntention() {\n return this.backend.skipNextFailedIntention({ msafeAddress: this.address });\n }\n\n async simulateIntention(): Promise<SimulationResult> {\n // Todo, move to API\n const txb = new TransactionBlock(); // await buildIntentionTransaction(this.suiClient, intention, this.address);\n txb.setSender(this.address);\n if (!txb.blockData.gasConfig.price) {\n const refGas = await this.suiClient.getReferenceGasPrice();\n txb.setGasPrice(refGas);\n }\n const payload = await txb.build({ client: this.suiClient });\n const dryRunResult = await this.suiClient.dryRunTransactionBlock({ transactionBlock: payload });\n\n const success = dryRunResult.effects.status.status === 'success';\n const errorMsg = dryRunResult.effects.status.error;\n const gasPrice = BigInt(txb.blockData.gasConfig.price as string);\n const { gasUsed } = dryRunResult.effects;\n\n return {\n success,\n errorMsg,\n gasPrice,\n gasUsed,\n dryRunResult,\n };\n }\n\n async executePendingTx(pending: PendingTx) {\n let gotSigs: Map<string, string>;\n let payload: string;\n if (pending.votes.length >= this.info.threshold) {\n gotSigs = new Map(pending.votes.map((vote) => [vote.userAddress, vote.signature]));\n payload = pending.payload;\n } else if (pending.rejectVotes && pending.rejectPayload && pending.rejectVotes?.length >= this.info.threshold) {\n gotSigs = new Map(pending.rejectVotes.map((vote) => [vote.userAddress, vote.signature]));\n payload = pending.rejectPayload;\n } else {\n throw new Error('Not enough signatures');\n }\n\n const sigs: SerializedSignature[] = [];\n for (let i = 0; i < this.info.owners.length; i++) {\n const owner = this.info.owners[i];\n const signature = gotSigs.get(owner.address);\n if (signature) {\n sigs.push(signature);\n }\n }\n const multiSignature = this.multiSig.combinePartialSignatures(sigs);\n return this.suiClient.executeTransactionBlock({\n transactionBlock: HexToUint8Array(payload),\n signature: multiSignature,\n options: { showEffects: true },\n });\n }\n\n get address() {\n return this.multiSig.address;\n }\n\n private get backend() {\n return this.globals.backend;\n }\n\n private get wallet() {\n return this.globals.wallet;\n }\n\n private async userAddress() {\n return this.globals.wallet.address();\n }\n\n private get suiClient() {\n return this.globals.suiClient;\n }\n}\n","export function stringToBuffer(s: string) {\n return Buffer.from(s, 'utf-8');\n}\n\nexport function Uint8ArrayToHex(b: Uint8Array): string {\n return `0x${Array.prototype.map.call(b, (x) => `0${x.toString(16)}`.slice(-2)).join('')}`;\n}\n\nexport function HexToUint8Array(hex: string): Uint8Array {\n return Uint8Array.from(Buffer.from(hex.startsWith('0x') ? hex.slice(2) : hex, 'hex'));\n}\n","import { SerializedSignature } from '@mysten/sui.js/cryptography';\nimport { verifyPersonalMessage, verifyTransactionBlock } from '@mysten/sui.js/verify';\n\nimport { stringToBuffer } from '@/utils/buffer';\nimport { Formatter } from '@/utils/format';\n\nexport class SignatureVerifier {\n static async getPublicKeyFromSignature(input: {\n message: Uint8Array;\n messageType: 'TransactionBlock' | 'Personal';\n signature: SerializedSignature;\n }) {\n if (input.messageType === 'TransactionBlock') {\n return verifyTransactionBlock(input.message, input.signature);\n }\n return verifyPersonalMessage(input.message, input.signature);\n }\n\n static async getPublicKeyFromPersonalSignature(input: { messageStr: string; signature: SerializedSignature }) {\n const message = stringToBuffer(input.messageStr);\n return this.getPublicKeyFromSignature({\n message,\n messageType: 'Personal',\n signature: input.signature,\n });\n }\n\n static async verifySignature(input: {\n message: Uint8Array;\n messageType: 'TransactionBlock' | 'Personal';\n signature: SerializedSignature;\n targetAddress: string;\n }) {\n const publicKey = await SignatureVerifier.getPublicKeyFromSignature(input);\n return Formatter.isSuiAddressEqual(publicKey.toSuiAddress(), input.targetAddress);\n }\n\n static async verifyPersonalSignature(input: {\n messageStr: string;\n signature: SerializedSignature;\n targetAddress: string;\n }) {\n const message = stringToBuffer(input.messageStr);\n return this.verifySignature({\n message,\n messageType: 'Personal',\n signature: input.signature,\n targetAddress: input.targetAddress,\n });\n }\n\n static async verifyTransactionSignature(input: {\n payload: Uint8Array;\n signature: SerializedSignature;\n targetAddress: string;\n }): Promise<boolean> {\n return this.verifySignature({\n messageType: 'TransactionBlock',\n message: input.payload,\n signature: input.signature,\n targetAddress: input.targetAddress,\n });\n }\n}\n","import { normalizeSuiAddress, normalizeStructTag } from '@mysten/sui.js/utils';\n\nimport { Coin } from '@/utils/coin';\n\nexport class Formatter {\n static normalizeSuiAddress(addr: string) {\n return normalizeSuiAddress(addr);\n }\n\n static normalizeStructTag(struct: string) {\n return normalizeStructTag(struct);\n }\n\n static isSuiAddressEqual(addr1: string, addr2: string) {\n return normalizeSuiAddress(addr1) === normalizeSuiAddress(addr2);\n }\n\n static isSuiStructEqual(struct1: string, struct2: string) {\n return normalizeStructTag(struct1) === normalizeStructTag(struct2);\n }\n\n static isCoinObjectType(struct: string) {\n return Coin.isCoin(struct);\n }\n}\n","import { CoinMetadata, SuiClient, SuiObjectData } from '@mysten/sui.js/client';\nimport { normalizeStructTag } from '@mysten/sui.js/utils';\n\n// CoinHelper is the coin helper to query for coin metadata.\nexport class CoinHelper {\n private _client: SuiClient;\n\n private _coinMetaReg: Map<string, CoinMetadata>;\n\n constructor(client: SuiClient) {\n this._client = client;\n this._coinMetaReg = new Map();\n }\n\n async getCoinMeta(coinType: string): Promise<CoinMetadata | undefined> {\n const normalized = normalizeStructTag(coinType);\n if (this._coinMetaReg.has(normalized)) {\n return this._coinMetaReg.get(normalized);\n }\n const meta = await this.queryCoinMeta(normalized);\n if (meta) {\n this._coinMetaReg.set(normalized, meta);\n }\n return meta;\n }\n\n private async queryCoinMeta(coinType: string): Promise<CoinMetadata | undefined> {\n const res = await this._client.getCoinMetadata({ coinType });\n return res || undefined;\n }\n}\n\n// Copied from sui/sdk/typescript/src/framework/framework.ts\n\nexport const COIN_TYPE_ARG_REGEX =\n /^0x0000000000000000000000000000000000000000000000000000000000000002::coin::Coin<(.+)>$/;\n\nexport class Coin {\n static isCoin(type: string | undefined | null): boolean {\n if (!type) {\n return false;\n }\n return normalizeStructTag(type).match(COIN_TYPE_ARG_REGEX) != null;\n }\n\n static getCoinType(type: string) {\n const [, res] = normalizeStructTag(type).match(COIN_TYPE_ARG_REGEX) ?? [];\n return res || null;\n }\n\n static getBalance(data: SuiObjectData): bigint | undefined {\n if (!Coin.isCoin(data.type)) {\n return undefined;\n }\n if (data.content?.dataType !== 'moveObject') {\n return undefined;\n }\n const { balance } = data.content?.fields as any;\n if (balance === undefined) {\n return undefined;\n }\n return BigInt(balance);\n }\n}\n","import { PublicKeySerde } from '@msafe/sui3-utils';\nimport { SuiClient, PaginatedTransactionResponse, PaginatedCoins, CoinStruct } from '@mysten/sui.js/client';\nimport { parseSerializedSignature, PublicKey, SerializedSignature } from '@mysten/sui.js/cryptography';\nimport { MultiSigPublicKey } from '@mysten/sui.js/multisig';\n\nimport { Formatter } from '@/utils/format';\n\nexport const SUI_COIN = '0x2::sui::SUI';\n\nexport async function getPublicKeyFromChain(suiClient: SuiClient, address: string): Promise<PublicKey | undefined> {\n let txs: PaginatedTransactionResponse;\n try {\n txs = await suiClient.queryTransactionBlocks({\n // Disable naming rule since the variable is defined by Mysten\n filter: { FromAddress: address },\n options: { showInput: true },\n limit: 2,\n });\n } catch (e) {\n // Currently when there is no history transaction, will report an error:\n // Error: byte deserialization failed, cause by: Odd number of digits\n // TODO: remove the catch logic when sui part is fixed;\n return undefined;\n }\n\n if (txs.data.length === 0 || !txs.data[0].transaction?.txSignatures) {\n return undefined;\n }\n const tx = txs.data[0];\n const signatures = tx.transaction?.txSignatures as string[];\n\n for (let i = 0; i !== signatures.length; i++) {\n const serializedSig = signatures[i];\n const pk = getAddressFromSignatures(serializedSig, address);\n if (!pk) {\n continue;\n }\n return pk;\n }\n return undefined;\n}\n\nfunction getAddressFromSignatures(serializedSig: SerializedSignature, targetAddress: string) {\n const decoded = parseSerializedSignature(serializedSig);\n switch (decoded.signatureScheme) {\n case 'MultiSig': {\n const multiSigAddress = new MultiSigPublicKey(decoded.multisig.multisig_pk).toSuiAddress();\n if (Formatter.isSuiAddressEqual(multiSigAddress, targetAddress)) {\n throw new Error('multi-sig wallet cannot be owner');\n }\n return undefined;\n }\n case 'ZkLogin': {\n if (Formatter.isSuiAddressEqual(decoded.zkLogin.address, targetAddress)) {\n throw new Error('ZkLogin wallet cannot be owner');\n }\n return undefined;\n }\n\n case 'ED25519':\n case 'Secp256k1':\n case 'Secp256r1': {\n const pk = PublicKeySerde.de({ publicKeyEncoded: decoded.publicKey, schema: decoded.signatureScheme });\n if (Formatter.isSuiAddressEqual(pk.toSuiAddress(), targetAddress)) {\n return pk;\n }\n return undefined;\n }\n\n default:\n throw new Error('Unknown schema');\n }\n}\n\nexport async function getAllCoins(input: { suiClient: SuiClient; owner: string; coinType: string | undefined }) {\n let hasNext = true;\n let cursor: string | undefined | null;\n const res: CoinStruct[] = [];\n while (hasNext) {\n const currentPage: PaginatedCoins = await input.suiClient.getCoins({\n owner: input.owner,\n coinType: input.coinType,\n cursor,\n });\n res.push(...currentPage.data);\n hasNext = currentPage.hasNextPage;\n cursor = currentPage.nextCursor;\n }\n return res;\n}\n","import { PagedData, Requester } from './requester';\n\nexport const REQUEST_PAGE_SIZE = 25;\n\nexport interface SuiIterator<T> {\n next: () => Promise<T | undefined>;\n hasNext: () => Promise<boolean>;\n}\n\nexport async function getAllFromIterator<T>(it: SuiIterator<T>): Promise<(T | undefined) | (T | undefined)[]> {\n const res: (T | undefined)[] = [];\n while (await it.hasNext()) {\n const val = await it.next();\n res.push(val);\n }\n if (res && Array.isArray(res[0])) {\n return res.flat(1) as T;\n }\n return res;\n}\n\nexport class PagedIterator<T> implements SuiIterator<(T | undefined)[]> {\n private curPage: PagedData<T> | undefined;\n\n private init: boolean;\n\n constructor(public readonly requester: Requester<T>) {\n this.curPage = undefined;\n this.init = true;\n }\n\n async hasNext(): Promise<boolean> {\n if (this.init) {\n if (!this.curPage) {\n this.curPage = await this.requester.doNextRequest();\n }\n return !!this.curPage.data?.length || this.curPage.hasNext;\n }\n if (!this.curPage) {\n throw new Error('invalid implementation of iterator');\n }\n return this.curPage.hasNext;\n }\n\n async next(): Promise<(T | undefined)[]> {\n if (this.init) {\n this.init = false;\n if (!this.curPage) {\n this.curPage = await this.requester.doNextRequest();\n }\n return this.curPage.data;\n }\n this.curPage = await this.requester.doNextRequest();\n return this.curPage.data;\n }\n}\n\nexport class EntryIterator<T> implements SuiIterator<T> {\n cursor: number;\n\n pager: PagedIterator<T>;\n\n curData: (T | undefined)[];\n\n constructor(public readonly requester: Requester<T>) {\n this.pager = new PagedIterator<T>(requester);\n this.curData = [];\n this.cursor = 0;\n }\n\n async hasNext(): Promise<boolean> {\n if (this.cursor < this.curData.length - 1) {\n return true;\n }\n return this.pager.hasNext();\n }\n\n async next(): Promise<T | undefined> {\n this.cursor += 1;\n while (this.cursor >= this.curData.length) {\n if (!(await this.pager.hasNext())) {\n throw new Error('not more data'); // Shall not happen for legit data source.\n } else {\n this.curData = await this.pager.next();\n this.cursor = 0;\n }\n }\n return this.curData[this.cursor];\n }\n}\n","import { SuiObjectResponse, SuiObjectDataOptions, SuiObjectData, SuiClient } from '@mysten/sui.js/client';\n\nimport { EntryIterator, getAllFromIterator, REQUEST_PAGE_SIZE, SuiIterator } from './iterator';\nimport { PagedData, Requester } from './requester';\n\n// TODO: setup testnet faucet and test this file\n\nexport type ObjectFilter = (objRes: SuiObjectResponse) => boolean;\n\n// OidIter is the iterator to give the list of object ids\nexport type OidIter = SuiIterator<string>;\n\nexport interface BatchObjectOptions {\n filter?: ObjectFilter;\n pageSize?: number;\n objectOptions?: SuiObjectDataOptions;\n}\n\n// getObjectsById get the list of objects by id.\n// Compared with the multiGetObject method defined by SUI, this method will do the pagination\n// for get object requests.\nexport async function getObjectsById(\n provider: SuiClient,\n ids: string[],\n options?: BatchObjectOptions,\n): Promise<(SuiObjectData | undefined)[]> {\n const oidIter = new ListOidIterator(ids);\n const iter = new ObjectBatchIterator(provider, oidIter, options);\n return (await getAllFromIterator(iter)) as (SuiObjectData | undefined)[];\n}\n\n// ListOidIterator is the iterator that iterate through a list of ids.\n// This iterator shall be used when the number requested objects is big\n// which is inappropriate to fit the requested objects into a single\n// request.\nexport class ListOidIterator implements OidIter {\n cursor: number;\n\n constructor(public readonly ids: string[]) {\n this.cursor = -1;\n }\n\n async hasNext(): Promise<boolean> {\n return this.cursor < this.ids.length - 1;\n }\n\n async next(): Promise<string> {\n this.cursor += 1;\n if (this.cursor >= this.ids.length) {\n throw new Error('invalid iterator implementation'); // Shall be unreachable\n }\n return this.ids[this.cursor];\n }\n}\n\nexport class ObjectBatchIterator extends EntryIterator<SuiObjectData> {\n constructor(\n public readonly provider: SuiClient,\n public readonly idIter: OidIter,\n public readonly options?: BatchObjectOptions,\n ) {\n super(new ObjectBatchRequester(provider, idIter, options));\n }\n}\n\n// TODO: Test with customize objects\nexport class ObjectBatchRequester implements Requester<SuiObjectData> {\n filter: ObjectFilter | undefined;\n\n pageSize: number;\n\n objectOptions: SuiObjectDataOptions;\n\n constructor(\n public readonly provider: SuiClient,\n public readonly stringIter: OidIter,\n public options?: BatchObjectOptions,\n ) {\n this.filter = options?.filter;\n this.pageSize = options?.pageSize || REQUEST_PAGE_SIZE;\n this.objectOptions = options?.objectOptions || {\n showType: true,\n showContent: true,\n };\n }\n\n async doNextRequest(): Promise<PagedData<SuiObjectData>> {\n const requestPage: string[] = [];\n while (requestPage.length < this.pageSize) {\n const hasNext = await this.stringIter.hasNext();\n if (!hasNext) {\n break;\n }\n const objId = await this.stringIter.next();\n if (objId) {\n requestPage.push(objId);\n }\n }\n const res: SuiObjectResponse[] = await this.provider.multiGetObjects({\n ids: requestPage,\n options: this.objectOptions,\n });\n let filtered: SuiObjectResponse[];\n if (this.filter) {\n const { filter } = this;\n filtered = res.filter((r: SuiObjectResponse) => filter?.(r));\n } else {\n filtered = res;\n }\n return {\n data: filtered.map((objRes) => objRes.data).filter((data) => data) as SuiObjectData[],\n hasNext: await this.stringIter.hasNext(),\n };\n }\n}\n\nexport async function getAllOwnedObjects(\n provider: SuiClient,\n owner: string,\n options?: BatchObjectOptions,\n): Promise<SuiObjectData[]> {\n const iter = new OwnedObjectIterator(provider, owner, options);\n return (await getAllFromIterator(iter)) as SuiObjectData[];\n}\n\nexport class OwnedObjectIterator extends EntryIterator<SuiObjectData> implements SuiIterator<SuiObjectData> {\n constructor(\n public readonly provider: SuiClient,\n public readonly owner: string,\n public readonly options?: BatchObjectOptions,\n ) {\n super(new OwnedObjectRequester(provider, owner, options));\n }\n}\n\nexport class OwnedObjectRequester implements Requester<SuiObjectData> {\n nextCursor: string | null;\n\n public filter: ObjectFilter | undefined;\n\n public pageSize: number;\n\n public objectOptions: SuiObjectDataOptions;\n\n constructor(\n public readonly provider: SuiClient,\n public readonly owner: string,\n public readonly options?: BatchObjectOptions,\n ) {\n this.nextCursor = null;\n this.filter = options?.filter;\n this.pageSize = options?.pageSize || REQUEST_PAGE_SIZE;\n this.objectOptions = options?.objectOptions || {\n showType: true,\n showContent: true,\n };\n }\n\n async doNextRequest(): Promise<PagedData<SuiObjectData>> {\n const res = await this.provider.getOwnedObjects({\n owner: this.owner,\n options: this.objectOptions,\n cursor: this.nextCursor,\n limit: this.pageSize,\n });\n this.nextCursor = res.nextCursor as string;\n let filtered: SuiObjectResponse[];\n if (this.filter) {\n const { filter } = this;\n filtered = res.data.filter((obj: SuiObjectResponse) => filter?.(obj));\n } else {\n filtered = res.data;\n }\n return {\n data: filtered.map((r: SuiObjectResponse) => r.data).filter((data) => data) as SuiObjectData[],\n hasNext: res.hasNextPage,\n };\n }\n}\n","import { PublicKey } from '@mysten/sui.js/src/cryptography';\n\nimport { MSafeGlobals } from '@/globals/MSafeGlobals';\nimport { getPublicKeyFromChain } from '@/utils/sui';\n\n/**\n * PublicKeyHelper is the helper to query for public keys from\n * backend and blockchain.\n */\nexport class PublicKeyHelper {\n private knownPublicKeys: Map<string, PublicKey>;\n\n constructor(public readonly globals: MSafeGlobals) {\n this.knownPublicKeys = new Map<string, PublicKey>();\n }\n\n async getPublicKey(address: string) {\n const cached = this.knownPublicKeys.get(address);\n if (cached) {\n return cached;\n }\n const pk = await this._getPublicKey(address);\n if (pk) {\n this.knownPublicKeys.set(address, pk);\n }\n return pk;\n }\n\n async getPublicKeyBatch(addresses: string[]): Promise<(PublicKey | undefined)[]> {\n const results: (PublicKey | undefined)[] = new Array(addresses.length).fill(undefined);\n\n // Query local cache first\n for (let i = 0; i < addresses.length; i++) {\n const address = addresses[i];\n results[i] = this.knownPublicKeys.get(address);\n }\n\n // Query backend in batch\n const emptyIndexes = results\n .map((elem, index) => (elem === undefined ? index : -1))\n .filter((index) => index !== -1);\n if (emptyIndexes.length === 0) {\n return results;\n }\n const backendResult = await this.globals.backend.getPublicKeyBatch(emptyIndexes.map((index) => addresses[index]));\n for (let i = 0; i < emptyIndexes.length; i++) {\n const index = emptyIndexes[i];\n results[index] = backendResult[i];\n }\n\n // Query the public key from blockchain\n for (let i = 0; i < results.length; i++) {\n if (results[i] === undefined) {\n results[i] = await this.getPublicKeyFromChain(addresses[i]);\n }\n }\n\n // Finally, write the public keys to the local cache\n for (let i = 0; i < addresses.length; i++) {\n if (results[i]) {\n this.knownPublicKeys.set(addresses[i], results[i] as PublicKey);\n }\n }\n return results;\n }\n\n private async _getPublicKey(address: string) {\n const pkBackend = await this.getPublicKeyFromBackend(address);\n if (pkBackend) {\n return pkBackend;\n }\n const pkChain = await this.getPublicKeyFromChain(address);\n if (pkChain) {\n return pkChain;\n }\n return undefined;\n }\n\n private async getPublicKeyFromBackend(address: string): Promise<PublicKey | undefined> {\n try {\n const pk = await this.globals.backend.getPublicKey(address);\n return pk;\n } catch (_) {\n return undefined;\n }\n }\n\n private async getPublicKeyFromChain(address: string): Promise<PublicKey | undefined> {\n return getPublicKeyFromChain(this.globals.suiClient, address);\n }\n}\n","import { SuiClient } from '@mysten/sui.js/client';\n\nimport { BackendImpl } from '@/backend/BackendImpl';\nimport { IBackend } from '@/backend/interface';\nimport { getMSafeConfig, MSafeConfig, MSafeConfigOptions, MSafeEnv } from '@/globals/const';\nimport { IWallet } from '@/types/wallet';\n\nexport class MSafeGlobals {\n public readonly backend: IBackend;\n\n public readonly suiClient: SuiClient;\n\n public readonly config: MSafeConfig;\n\n _wallet: IWallet | undefined;\n\n constructor(input: { backend: IBackend; suiClient: SuiClient; config: MSafeConfig }) {\n this.backend = input.backend;\n this.suiClient = input.suiClient;\n this.config = input.config;\n }\n\n static async New(env: MSafeEnv, options?: MSafeConfigOptions) {\n const config = getMSafeConfig(env, options);\n const suiClient = new SuiClient(config.suiClient);\n const backend = new BackendImpl(config.backend.url);\n return new MSafeGlobals({\n backend,\n suiClient,\n config,\n });\n }\n\n connectWallet(wallet: IWallet) {\n this._wallet = wallet;\n }\n\n get wallet() {\n if (!this._wallet) {\n throw new Error('wallet not connected');\n }\n return this._wallet;\n }\n\n set wallet(val: IWallet) {\n this._wallet = val;\n }\n}\n","import {\n GetHistoryTransactionsResponse,\n GetPendingTransactionResponse,\n GetTransactionIntentionsResponse,\n IAuthLoginReq,\n IAuthLoginResp,\n IBuildTransactionRequest,\n ICreateMSafeReq,\n IGetAddressBookResult,\n IGetHistoryTransactionsRequest,\n IGetIntentionsRequest,\n IGetMSafeQuery,\n IGetMSafesQuery,\n IGetPendingTransactionRequest,\n IGetPublicKeyBatchQuery,\n IGetPublicKeyBatchResp,\n IMSafeConfig,\n IMSafeInfoResp,\n IPageOptions,\n IPagedResult,\n IProposeIntentionRequest,\n ISkipIntentionRequest,\n IUpdateMSafeStatusReq,\n IUserInfoResp,\n IVoteTransactionRequest,\n JWTToken,\n PublicKeySerde,\n TxIntention,\n UpdateAddressBookEntry,\n UserMSafeStatus,\n} from '@msafe/sui3-utils';\nimport { SerializedSignature } from '@mysten/sui.js/cryptography';\nimport { PublicKey } from '@mysten/sui.js/src/cryptography';\nimport axios from 'axios';\n\nimport { IBackend } from '@/backend/interface';\n\nexport class BackendImpl implements IBackend {\n private _token: JWTToken;\n\n constructor(private readonly apiURL: string) {}\n\n async authSign(input: IAuthLoginReq): Promise<JWTToken> {\n const res = await axios.post<IAuthLoginResp>(`${this.apiURL}/auth/login`, input);\n // TODO unify response struct\n if (res.status !== 200 && res.status !== 201) {\n throw new Error(`invalid authSign return: ${res}`);\n }\n this._token = res.data.accessToken;\n return this._token;\n }\n\n async verifyToken(jwt: JWTToken): Promise<boolean> {\n try {\n const res = await axios.get(`${this.apiURL}/auth`, { headers: this.headers(jwt) });\n return res.status === 200;\n } catch (_) {\n return false;\n }\n }\n\n setJWTToken(token: JWTToken) {\n this._token = token;\n }\n\n async getPublicKey(address: string): Promise<PublicKey | undefined> {\n return (await this.getPublicKeyBatch([address]))[0];\n }\n\n async getPublicKeyBatch(addresses: string[]): Promise<(PublicKey | undefined)[]> {\n const query: IGetPublicKeyBatchQuery = {\n userAddressList: addresses,\n };\n const res = await axios.get<IGetPublicKeyBatchResp>(`${this.apiURL}/user/public-keys`, {\n params: query,\n headers: this.headers(),\n });\n\n // TODO unify response struct\n if (res.status !== 200 && res.status !== 201) {\n throw new Error(`invalid getPublicKeyBatch return: ${res}`);\n }\n return res.data?.map((publicKeyWithSchema) =>\n publicKeyWithSchema ? PublicKeySerde.de(publicKeyWithSchema) : undefined,\n );\n }\n\n async getMSafeAccountInfo(msafeAddress: string): Promise<IMSafeConfig> {\n const q: IGetMSafeQuery = {\n msafeAddress,\n };\n const res = await axios.get<IMSafeInfoResp>(`${this.apiURL}/msafe`, {\n params: q,\n headers: this.headers(),\n });\n // TODO unify response struct\n if (res.status !== 200 && res.status !== 201) {\n throw new Error(`invalid getPublicKeyBatch return: ${res}`);\n }\n return BackendImpl.toMSafeConfig(res.data);\n }\n\n async getUserInfo(): Promise<IUserInfoResp> {\n const userRes = await axios.get<IUserInfoResp>(`${this.apiURL}/user`, {\n headers: this.headers(),\n });\n // TODO unify response struct\n if (userRes.status !== 200 && userRes.status !== 201) {\n throw new Error(`invalid getPublicKeyBatch return: ${userRes}`);\n }\n return userRes.data;\n }\n\n async getOwnedMSafeByStatus(input: {\n status?: UserMSafeStatus;\n pagination?: IPageOptions;\n }): Promise<IPagedResult<IMSafeConfig>> {\n const q: IGetMSafesQuery = {\n status: input.status ?? UserMSafeStatus.active,\n ...(input.pagination\n ? {\n page: input.pagination.page.toString(),\n limit: input.pagination.limit.toString(),\n }\n : {}),\n };\n const res = await axios.get<IPagedResult<IMSafeInfoResp>>(`${this.apiURL}/msafe/owned`, {\n params: q,\n headers: this.headers(),\n });\n if (res.status !== 200 && res.status !== 201) {\n throw new Error(`invalid getOwnedMSafeByStatus return: ${res}`);\n }\n return {\n data: res.data.data.map(BackendImpl.toMSafeConfig),\n meta: res.data.meta,\n };\n }\n\n async updateMSafeStatus(input: { msafeAddress: string; status: UserMSafeStatus }): Promise<void> {\n const p: IUpdateMSafeStatusReq = input;\n const res = await axios.post(`${this.apiURL}/msafe/status`, p, { headers: this.headers() });\n if (res.status !== 200 && res.status !== 201) {\n throw new Error(`Invalid updateMSafeStatus return: ${res}`);\n }\n }\n\n async getPendingTransactions(input: IGetPendingTransactionRequest): Promise<GetPendingTransactionResponse> {\n const res = await axios.get<GetPendingTransactionResponse>(`${this.apiURL}/transaction/pending`, {\n params: input,\n headers: this.headers(),\n });\n if (res.status !== 200 && res.status !== 201) {\n throw new Error(`invalid getPublicKeyBatch return: ${res}`);\n }\n return res.data;\n }\n\n async getHistoryTransactions(input: IGetHistoryTransactionsRequest): Promise<GetHistoryTransactionsResponse> {\n const res = await axios.get<GetHistoryTransactionsResponse>(`${this.apiURL}/transaction/history`, {\n params: input,\n headers: this.headers(),\n });\n if (res.status !== 200 && res.status !== 201) {\n throw new Error(`invalid getCurrentSequenceNumber return: ${res}`);\n }\n return res.data;\n }\n\n async getFutureIntentions(input: IGetIntentionsRequest): Promise<GetTransactionIntentionsResponse> {\n const res = await axios.get<GetTransactionIntentionsResponse>(`${this.apiURL}/transaction/intention`, {\n params: input,\n headers: this.headers(),\n });\n if (res.status !== 200 && res.status !== 201) {\n throw new Error(`invalid getCurrentSequenceNumber return: ${res}`);\n }\n return res.data;\n }\n\n async getCurrentSequenceNumber(address: string): Promise<number> {\n const res = await axios.get<number>(`${this.apiURL}/transaction/sn/current`, {\n params: {\n msafeAddress: address,\n },\n headers: this.headers(),\n });\n if (res.status !== 200 && res.status !== 201) {\n throw new Error(`invalid getCurrentSequenceNumber return: ${res}`);\n }\n return res.data;\n }\n\n async getNextSequenceNumber(address: string): Promise<number> {\n const res = await axios.get<number>(`${this.apiURL}/transaction/sn/next`, {\n params: {\n msafeAddress: address,\n },\n headers: this.headers(),\n });\n if (res.status !== 200 && res.status !== 201) {\n throw new Error(`invalid getNextSequenceNumber return: ${res}`);\n }\n return res.data;\n }\n\n async createMSafeAccount(input: ICreateMSafeReq): Promise<void> {\n const res = await axios.post(`${this.apiURL}/msafe/create`, input, {\n headers: this.headers(),\n });\n if (res.status !== 200 && res.status !== 201) {\n throw new Error(`invalid createMSafeAccount return: ${res}`);\n }\n }\n\n async proposeIntention(input: IProposeIntentionRequest): Promise<void> {\n const res = await axios.post(`${this.apiURL}/transaction/intention`, input, { headers: this.headers() });\n if (res.status !== 200 && res.status !== 201) {\n throw new Error(`invalid proposeIntention return: ${res}`);\n }\n }\n\n // TODO later\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n async proposePendingTransaction(_input: {\n intention: TxIntention;\n userAddress: string;\n msafeAddress: string;\n digest: string;\n signature: SerializedSignature;\n }): Promise<void> {\n return undefined;\n }\n\n async rejectCurrentTx(input: IVoteTransactionRequest) {\n const res = await axios.post(`${this.apiURL}/transaction/pending/reject`, input, {\n headers: this.headers(),\n });\n if (res.status !== 200 && res.status !== 201) {\n throw new Error(`invalid voteForTransaction return: ${res}`);\n }\n }\n\n async voteForTransaction(input: IVoteTransactionRequest) {\n const res = await axios.post(`${this.apiURL}/transaction/pending/vote`, input, {\n headers: this.headers(),\n });\n if (res.status !== 200 && res.status !== 201) {\n throw new Error(`invalid voteForTransaction return: ${res}`);\n }\n }\n\n async buildNextIntentionAndAddToPending(input: IBuildTransactionRequest) {\n const res = await axios.post(`${this.apiURL}/transaction/pending/build`, input, { headers: this.headers() });\n if (res.status !== 200 && res.status !== 201) {\n throw new Error(`invalid buildNextIntentionAndAddToPending return: ${res}`);\n }\n }\n\n async skipNextFailedIntention(input: ISkipIntentionRequest) {\n const res = await axios.post(`${this.apiURL}/transaction/pending/skip`, input, { headers: this.headers() });\n if (res.status !== 200 && res.status !== 201) {\n throw new Error(`invalid skipNextFailedIntention return: ${res}`);\n }\n }\n\n async getAddressBookEntries(pagination?: IPageOptions): Promise<IGetAddressBookResult> {\n const res = await axios.get<IGetAddressBookResult>(`${this.apiURL}/address-book`, {\n headers: this.headers(),\n params: pagination,\n });\n if (res.status !== 200) {\n throw new Error(`Invalid address-book return: ${res}`);\n }\n return res.data;\n }\n\n async updateAddressBook(input: { updates: UpdateAddressBookEntry[]; signature: SerializedSignature }) {\n const res = await axios.post(`${this.apiURL}/address-book`, input, { headers: this.headers() });\n if (res.status !== 200 && res.status !== 201) {\n throw new Error(`invalid updateAddressBook return: ${res}`);\n }\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n async processExecutedTransaction(_digest: string) {\n return undefined;\n }\n\n private headers(token?: string) {\n return { Authorization: `Bearer ${token || this._token}` };\n }\n\n private static toMSafeConfig(resp: IMSafeInfoResp): IMSafeConfig {\n return {\n ...resp,\n owners: resp.owners.map((owner) => ({\n address: owner.address,\n weight: owner.weight,\n publicKey: PublicKeySerde.de({\n publicKeyEncoded: owner.publicKeyEncoded,\n schema: owner.schema,\n }),\n })),\n };\n }\n}\n","export enum MSafeEnv {\n local = 'local',\n unit = 'unit',\n dev = 'dev',\n prev = 'prev',\n prod = 'prod',\n}\n\nexport interface MSafeConfig {\n suiClient: {\n url: string;\n };\n backend: {\n url: string;\n };\n syncingURL: string;\n}\n\nexport interface MSafeConfigOptions {\n suiClient?: {\n url?: string;\n };\n backend?: {\n url?: string;\n };\n}\nexport const MSAFE_APPLICATION = 'msafe';\n\nexport const TESTNET_RPC_URL = 'https://sui-testnet.blockvision.org/v1/2Sgk89ivT64MnKdcGzjmyjY2ndD';\nexport const MAINNET_RPC_URL = 'https://sui-mainnet.blockvision.org/v1/2Sgk7NPvqkd7mESYkxF01yX15l7';\n\nexport const LOCAL_API_URL = 'http://127.0.0.1:3000';\nexport const LOCAL_SYNCING_URL = 'http://127.0.0.1:3001';\n\nexport const DEV_API_URL = 'http://13.56.226.148';\nexport const DEV_SYNCING_URL = 'http://52.53.228.20';\n\nexport const ENV_CONFIGS = new Map<MSafeEnv, MSafeConfig>([\n [\n MSafeEnv.unit,\n {\n suiClient: {\n url: TESTNET_RPC_URL,\n },\n backend: {\n url: LOCAL_API_URL,\n },\n syncingURL: LOCAL_SYNCING_URL,\n },\n ],\n [\n MSafeEnv.local,\n {\n suiClient: {\n url: TESTNET_RPC_URL,\n },\n backend: {\n url: LOCAL_API_URL,\n },\n syncingURL: LOCAL_SYNCING_URL,\n },\n ],\n [\n MSafeEnv.dev,\n {\n suiClient: {\n url: TESTNET_RPC_URL,\n },\n backend: {\n url: DEV_API_URL,\n },\n syncingURL: DEV_SYNCING_URL,\n },\n ],\n]);\n\nexport function getMSafeConfig(env: MSafeEnv, options?: MSafeConfigOptions) {\n const config = ENV_CONFIGS.get(env);\n if (!config) {\n throw new Error('Unknown environment');\n }\n if (options?.suiClient?.url) {\n config.suiClient.url = options.suiClient.url;\n }\n if (options?.backend?.url) {\n config.backend.url = options.backend.url;\n }\n return config;\n}\n"],"mappings":";AAAA,SAAS,iBAAiC,gBAAgB,4BAA4B;AAO/E,IAAM,eAAN,MAAmB;AAAA,EACxB,YACkB,SACA,UAChB;AAFgB;AACA;AAAA,EACf;AAAA,EAEH,MAAM,kBAAkB,WAAqB;AAC3C,WAAO,KAAK,SAAS,kBAAkB,SAAS;AAAA,EAClD;AAAA,EAEA,MAAM,sBAAsB,MAAuB;AACjD,UAAM,WAAW,MAAM,KAAK,8BAA8B,IAAI;AAC9D,UAAM,KAAK,IAAI,gBAAgB,QAAQ;AACvC,WAAO,GAAG;AAAA,EACZ;AAAA;AAAA,EAGA,MAAM,mBAAmB,YAA6B;AAEpD,WAAO,KAAK,sBAAsB,UAAU;AAAA,EAC9C;AAAA,EAEA,MAAM,oBAAoB,cAA+B;AACvD,UAAM,eAAe,MAAM,KAAK,mBAAmB,YAAY;AAE/D,UAAM,iBAAiB,qBAAqB,mBAAmB,YAAY;AAC3E,UAAM,YAAY,MAAM,KAAK,QAAQ,OAAO,oBAAoB,EAAE,YAAY,eAAe,CAAC;AAE9F,UAAM,KAAK,gBAAgB,cAAc,UAAU,SAAS;AAC5D,WAAO;AAAA,EACT;AAAA,EAEA,MAAc,8BAA8B,MAAgD;AAC1F,UAAM,aAAa,MAAM,KAAK,kBAAkB,KAAK,OAAO,IAAI,CAAC,UAAU,MAAM,OAAO,CAAC;AACzF,eAAW,QAAQ,CAAC,IAAI,MAAM;AAC5B,UAAI,OAAO,QAAW;AACpB,cAAM,IAAI,MAAM,mCAAmC,KAAK,OAAO,CAAC,EAAE,OAAO,EAAE;AAAA,MAC7E;AAAA,IACF,CAAC;AACD,WAAO;AAAA,MACL,WAAW,KAAK;AAAA,MAChB,kBAAkB,KAAK,OAAO,IAAI,CAAC,OAAO,OAAO;AAAA,QAC/C,WAAW,WAAW,CAAC;AAAA,QACvB,QAAQ,MAAM;AAAA,MAChB,EAAE;AAAA,MACF,eAAe,KAAK;AAAA,IACtB;AAAA,EACF;AAAA,EAEA,MAAc,gBAAgB,YAA6B,WAAgC;AACzF,UAAM,MAAM,MAAM,KAAK,SAAS,kBAAkB,WAAW,OAAO,IAAI,CAAC,UAAU,MAAM,OAAO,CAAC;AACjG,UAAM,KAAK,QAAQ,QAAQ,mBAAmB;AAAA,MAC5C,QAAQ,WAAW,OAAO,IAAI,CAAC,OAAO,OAAO;AAAA,QAC3C,SAAS,MAAM;AAAA,QACf,QAAQ,MAAM;AAAA,QACd,GAAG,eAAe,IAAI,IAAI,CAAC,CAAc;AAAA,MAC3C,EAAE;AAAA,MACF,WAAW,WAAW;AAAA,MACtB,MAAM,WAAW;AAAA;AAAA,MACjB,aAAa,WAAW;AAAA;AAAA,MACxB,eAAe,WAAW;AAAA,MAC1B;AAAA,IACF,CAAC;AAAA,EACH;AACF;;;ACvEA;AAAA,EAKE,wBAAAA;AAAA,EACA,mBAAAC;AAAA,OACK;;;ACPP,SAAuB,wBAAAC,6BAAoD;AAIpE,IAAM,iBAAN,MAAqB;AAAA,EAC1B,YAA4B,SAAuB;AAAvB;AAAA,EAAwB;AAAA,EAEpD,MAAM,WAAW,YAA2B;AAC1C,WAAO,KAAK,QAAQ,QAAQ,sBAAsB,UAAU;AAAA,EAC9D;AAAA,EAEA,MAAM,OAAO,SAAmC;AAC9C,UAAM,aAAaA,sBAAqB,yBAAyB,OAAO;AACxE,UAAM,MAAM,MAAM,KAAK,QAAQ,OAAO,oBAAoB,EAAE,WAAW,CAAC;AACxE,WAAO,KAAK,QAAQ,QAAQ,kBAAkB,EAAE,SAAS,WAAW,IAAI,UAAU,CAAC;AAAA,EACrF;AACF;;;ACZO,IAAM,gBAAN,MAAoB;AAAA,EACzB,YAA4B,SAAuB;AAAvB;AAAA,EAAwB;AAAA,EAEpD,MAAM,iBAAiB,QAAyB,YAAgE;AAC9G,WAAO,KAAK,QAAQ,QAAQ,sBAAsB,EAAE,QAAQ,WAAW,CAAC;AAAA,EAC1E;AAAA,EAEA,MAAM,kBAAkB,cAAsB,QAAyB;AACrE,WAAO,KAAK,QAAQ,QAAQ,kBAAkB,EAAE,cAAc,OAAO,CAAC;AAAA,EACxE;AACF;;;ACdA;AAAA,EAIE,mBAAAC;AAAA,EAEA,wBAAAC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAEA;AAAA,EACA;AAAA,OACK;AAIP,SAAS,wBAAwB;AACjC,SAAS,sBAAAC,2BAA0B;;;AClB5B,SAAS,eAAe,GAAW;AACxC,SAAO,OAAO,KAAK,GAAG,OAAO;AAC/B;AAEO,SAAS,gBAAgB,GAAuB;AACrD,SAAO,KAAK,MAAM,UAAU,IAAI,KAAK,GAAG,CAAC,MAAM,IAAI,EAAE,SAAS,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC;AACzF;AAEO,SAAS,gBAAgB,KAAyB;AACvD,SAAO,WAAW,KAAK,OAAO,KAAK,IAAI,WAAW,IAAI,IAAI,IAAI,MAAM,CAAC,IAAI,KAAK,KAAK,CAAC;AACtF;;;ACTA,SAAS,uBAAuB,8BAA8B;;;ACD9D,SAAS,qBAAqB,sBAAAC,2BAA0B;;;ACCxD,SAAS,0BAA0B;AAG5B,IAAM,aAAN,MAAiB;AAAA,EACd;AAAA,EAEA;AAAA,EAER,YAAY,QAAmB;AAC7B,SAAK,UAAU;AACf,SAAK,eAAe,oBAAI,IAAI;AAAA,EAC9B;AAAA,EAEA,MAAM,YAAY,UAAqD;AACrE,UAAM,aAAa,mBAAmB,QAAQ;AAC9C,QAAI,KAAK,aAAa,IAAI,UAAU,GAAG;AACrC,aAAO,KAAK,aAAa,IAAI,UAAU;AAAA,IACzC;AACA,UAAM,OAAO,MAAM,KAAK,cAAc,UAAU;AAChD,QAAI,MAAM;AACR,WAAK,aAAa,IAAI,YAAY,IAAI;AAAA,IACxC;AACA,WAAO;AAAA,EACT;AAAA,EAEA,MAAc,cAAc,UAAqD;AAC/E,UAAM,MAAM,MAAM,KAAK,QAAQ,gBAAgB,EAAE,SAAS,CAAC;AAC3D,WAAO,OAAO;AAAA,EAChB;AACF;AAIO,IAAM,sBACX;AAEK,IAAM,OAAN,MAAM,MAAK;AAAA,EAChB,OAAO,OAAO,MAA0C;AACtD,QAAI,CAAC,MAAM;AACT,aAAO;AAAA,IACT;AACA,WAAO,mBAAmB,IAAI,EAAE,MAAM,mBAAmB,KAAK;AAAA,EAChE;AAAA,EAEA,OAAO,YAAY,MAAc;AAC/B,UAAM,CAAC,EAAE,GAAG,IAAI,mBAAmB,IAAI,EAAE,MAAM,mBAAmB,KAAK,CAAC;AACxE,WAAO,OAAO;AAAA,EAChB;AAAA,EAEA,OAAO,WAAW,MAAyC;AACzD,QAAI,CAAC,MAAK,OAAO,KAAK,IAAI,GAAG;AAC3B,aAAO;AAAA,IACT;AACA,QAAI,KAAK,SAAS,aAAa,cAAc;AAC3C,aAAO;AAAA,IACT;AACA,UAAM,EAAE,QAAQ,IAAI,KAAK,SAAS;AAClC,QAAI,YAAY,QAAW;AACzB,aAAO;AAAA,IACT;AACA,WAAO,OAAO,OAAO;AAAA,EACvB;AACF;;;AD3DO,IAAM,YAAN,MAAgB;AAAA,EACrB,OAAO,oBAAoB,MAAc;AACvC,WAAO,oBAAoB,IAAI;AAAA,EACjC;AAAA,EAEA,OAAO,mBAAmB,QAAgB;AACxC,WAAOC,oBAAmB,MAAM;AAAA,EAClC;AAAA,EAEA,OAAO,kBAAkB,OAAe,OAAe;AACrD,WAAO,oBAAoB,KAAK,MAAM,oBAAoB,KAAK;AAAA,EACjE;AAAA,EAEA,OAAO,iBAAiB,SAAiB,SAAiB;AACxD,WAAOA,oBAAmB,OAAO,MAAMA,oBAAmB,OAAO;AAAA,EACnE;AAAA,EAEA,OAAO,iBAAiB,QAAgB;AACtC,WAAO,KAAK,OAAO,MAAM;AAAA,EAC3B;AACF;;;ADlBO,IAAM,oBAAN,MAAM,mBAAkB;AAAA,EAC7B,aAAa,0BAA0B,OAIpC;AACD,QAAI,MAAM,gBAAgB,oBAAoB;AAC5C,aAAO,uBAAuB,MAAM,SAAS,MAAM,SAAS;AAAA,IAC9D;AACA,WAAO,sBAAsB,MAAM,SAAS,MAAM,SAAS;AAAA,EAC7D;AAAA,EAEA,aAAa,kCAAkC,OAA+D;AAC5G,UAAM,UAAU,eAAe,MAAM,UAAU;AAC/C,WAAO,KAAK,0BAA0B;AAAA,MACpC;AAAA,MACA,aAAa;AAAA,MACb,WAAW,MAAM;AAAA,IACnB,CAAC;AAAA,EACH;AAAA,EAEA,aAAa,gBAAgB,OAK1B;AACD,UAAM,YAAY,MAAM,mBAAkB,0BAA0B,KAAK;AACzE,WAAO,UAAU,kBAAkB,UAAU,aAAa,GAAG,MAAM,aAAa;AAAA,EAClF;AAAA,EAEA,aAAa,wBAAwB,OAIlC;AACD,UAAM,UAAU,eAAe,MAAM,UAAU;AAC/C,WAAO,KAAK,gBAAgB;AAAA,MAC1B;AAAA,MACA,aAAa;AAAA,MACb,WAAW,MAAM;AAAA,MACjB,eAAe,MAAM;AAAA,IACvB,CAAC;AAAA,EACH;AAAA,EAEA,aAAa,2BAA2B,OAInB;AACnB,WAAO,KAAK,gBAAgB;AAAA,MAC1B,aAAa;AAAA,MACb,SAAS,MAAM;AAAA,MACf,WAAW,MAAM;AAAA,MACjB,eAAe,MAAM;AAAA,IACvB,CAAC;AAAA,EACH;AACF;;;AG/DA,SAAS,kBAAAC,uBAAsB;AAE/B,SAAS,gCAAgE;AACzE,SAAS,yBAAyB;AAI3B,IAAM,WAAW;AAExB,eAAsB,sBAAsB,WAAsB,SAAiD;AACjH,MAAI;AACJ,MAAI;AACF,UAAM,MAAM,UAAU,uBAAuB;AAAA;AAAA,MAE3C,QAAQ,EAAE,aAAa,QAAQ;AAAA,MAC/B,SAAS,EAAE,WAAW,KAAK;AAAA,MAC3B,OAAO;AAAA,IACT,CAAC;AAAA,EACH,SAAS,GAAG;AAIV,WAAO;AAAA,EACT;AAEA,MAAI,IAAI,KAAK,WAAW,KAAK,CAAC,IAAI,KAAK,CAAC,EAAE,aAAa,cAAc;AACnE,WAAO;AAAA,EACT;AACA,QAAM,KAAK,IAAI,KAAK,CAAC;AACrB,QAAM,aAAa,GAAG,aAAa;AAEnC,WAAS,IAAI,GAAG,MAAM,WAAW,QAAQ,KAAK;AAC5C,UAAM,gBAAgB,WAAW,CAAC;AAClC,UAAM,KAAK,yBAAyB,eAAe,OAAO;AAC1D,QAAI,CAAC,IAAI;AACP;AAAA,IACF;AACA,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAEA,SAAS,yBAAyB,eAAoC,eAAuB;AAC3F,QAAM,UAAU,yBAAyB,aAAa;AACtD,UAAQ,QAAQ,iBAAiB;AAAA,IAC/B,KAAK,YAAY;AACf,YAAM,kBAAkB,IAAI,kBAAkB,QAAQ,SAAS,WAAW,EAAE,aAAa;AACzF,UAAI,UAAU,kBAAkB,iBAAiB,aAAa,GAAG;AAC/D,cAAM,IAAI,MAAM,kCAAkC;AAAA,MACpD;AACA,aAAO;AAAA,IACT;AAAA,IACA,KAAK,WAAW;AACd,UAAI,UAAU,kBAAkB,QAAQ,QAAQ,SAAS,aAAa,GAAG;AACvE,cAAM,IAAI,MAAM,gCAAgC;AAAA,MAClD;AACA,aAAO;AAAA,IACT;AAAA,IAEA,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK,aAAa;AAChB,YAAM,KAAKC,gBAAe,GAAG,EAAE,kBAAkB,QAAQ,WAAW,QAAQ,QAAQ,gBAAgB,CAAC;AACrG,UAAI,UAAU,kBAAkB,GAAG,aAAa,GAAG,aAAa,GAAG;AACjE,eAAO;AAAA,MACT;AACA,aAAO;AAAA,IACT;AAAA,IAEA;AACE,YAAM,IAAI,MAAM,gBAAgB;AAAA,EACpC;AACF;AAEA,eAAsB,YAAY,OAA8E;AAC9G,MAAI,UAAU;AACd,MAAI;AACJ,QAAM,MAAoB,CAAC;AAC3B,SAAO,SAAS;AACd,UAAM,cAA8B,MAAM,MAAM,UAAU,SAAS;AAAA,MACjE,OAAO,MAAM;AAAA,MACb,UAAU,MAAM;AAAA,MAChB;AAAA,IACF,CAAC;AACD,QAAI,KAAK,GAAG,YAAY,IAAI;AAC5B,cAAU,YAAY;AACtB,aAAS,YAAY;AAAA,EACvB;AACA,SAAO;AACT;;;ACvFO,IAAM,oBAAoB;AAOjC,eAAsB,mBAAsB,IAAkE;AAC5G,QAAM,MAAyB,CAAC;AAChC,SAAO,MAAM,GAAG,QAAQ,GAAG;AACzB,UAAM,MAAM,MAAM,GAAG,KAAK;AAC1B,QAAI,KAAK,GAAG;AAAA,EACd;AACA,MAAI,OAAO,MAAM,QAAQ,IAAI,CAAC,CAAC,GAAG;AAChC,WAAO,IAAI,KAAK,CAAC;AAAA,EACnB;AACA,SAAO;AACT;AAEO,IAAM,gBAAN,MAAiE;AAAA,EAKtE,YAA4B,WAAyB;AAAzB;AAC1B,SAAK,UAAU;AACf,SAAK,OAAO;AAAA,EACd;AAAA,EAPQ;AAAA,EAEA;AAAA,EAOR,MAAM,UAA4B;AAChC,QAAI,KAAK,MAAM;AACb,UAAI,CAAC,KAAK,SAAS;AACjB,aAAK,UAAU,MAAM,KAAK,UAAU,cAAc;AAAA,MACpD;AACA,aAAO,CAAC,CAAC,KAAK,QAAQ,MAAM,UAAU,KAAK,QAAQ;AAAA,IACrD;AACA,QAAI,CAAC,KAAK,SAAS;AACjB,YAAM,IAAI,MAAM,oCAAoC;AAAA,IACtD;AACA,WAAO,KAAK,QAAQ;AAAA,EACtB;AAAA,EAEA,MAAM,OAAmC;AACvC,QAAI,KAAK,MAAM;AACb,WAAK,OAAO;AACZ,UAAI,CAAC,KAAK,SAAS;AACjB,aAAK,UAAU,MAAM,KAAK,UAAU,cAAc;AAAA,MACpD;AACA,aAAO,KAAK,QAAQ;AAAA,IACtB;AACA,SAAK,UAAU,MAAM,KAAK,UAAU,cAAc;AAClD,WAAO,KAAK,QAAQ;AAAA,EACtB;AACF;AAEO,IAAM,gBAAN,MAAiD;AAAA,EAOtD,YAA4B,WAAyB;AAAzB;AAC1B,SAAK,QAAQ,IAAI,cAAiB,SAAS;AAC3C,SAAK,UAAU,CAAC;AAChB,SAAK,SAAS;AAAA,EAChB;AAAA,EAVA;AAAA,EAEA;AAAA,EAEA;AAAA,EAQA,MAAM,UAA4B;AAChC,QAAI,KAAK,SAAS,KAAK,QAAQ,SAAS,GAAG;AACzC,aAAO;AAAA,IACT;AACA,WAAO,KAAK,MAAM,QAAQ;AAAA,EAC5B;AAAA,EAEA,MAAM,OAA+B;AACnC,SAAK,UAAU;AACf,WAAO,KAAK,UAAU,KAAK,QAAQ,QAAQ;AACzC,UAAI,CAAE,MAAM,KAAK,MAAM,QAAQ,GAAI;AACjC,cAAM,IAAI,MAAM,eAAe;AAAA,MACjC,OAAO;AACL,aAAK,UAAU,MAAM,KAAK,MAAM,KAAK;AACrC,aAAK,SAAS;AAAA,MAChB;AAAA,IACF;AACA,WAAO,KAAK,QAAQ,KAAK,MAAM;AAAA,EACjC;AACF;;;AC2BA,eAAsB,mBACpB,UACA,OACA,SAC0B;AAC1B,QAAM,OAAO,IAAI,oBAAoB,UAAU,OAAO,OAAO;AAC7D,SAAQ,MAAM,mBAAmB,IAAI;AACvC;AAEO,IAAM,sBAAN,cAAkC,cAAmE;AAAA,EAC1G,YACkB,UACA,OACA,SAChB;AACA,UAAM,IAAI,qBAAqB,UAAU,OAAO,OAAO,CAAC;AAJxC;AACA;AACA;AAAA,EAGlB;AACF;AAEO,IAAM,uBAAN,MAA+D;AAAA,EASpE,YACkB,UACA,OACA,SAChB;AAHgB;AACA;AACA;AAEhB,SAAK,aAAa;AAClB,SAAK,SAAS,SAAS;AACvB,SAAK,WAAW,SAAS,YAAY;AACrC,SAAK,gBAAgB,SAAS,iBAAiB;AAAA,MAC7C,UAAU;AAAA,MACV,aAAa;AAAA,IACf;AAAA,EACF;AAAA,EApBA;AAAA,EAEO;AAAA,EAEA;AAAA,EAEA;AAAA,EAgBP,MAAM,gBAAmD;AACvD,UAAM,MAAM,MAAM,KAAK,SAAS,gBAAgB;AAAA,MAC9C,OAAO,KAAK;AAAA,MACZ,SAAS,KAAK;AAAA,MACd,QAAQ,KAAK;AAAA,MACb,OAAO,KAAK;AAAA,IACd,CAAC;AACD,SAAK,aAAa,IAAI;AACtB,QAAI;AACJ,QAAI,KAAK,QAAQ;AACf,YAAM,EAAE,OAAO,IAAI;AACnB,iBAAW,IAAI,KAAK,OAAO,CAAC,QAA2B,SAAS,GAAG,CAAC;AAAA,IACtE,OAAO;AACL,iBAAW,IAAI;AAAA,IACjB;AACA,WAAO;AAAA,MACL,MAAM,SAAS,IAAI,CAAC,MAAyB,EAAE,IAAI,EAAE,OAAO,CAAC,SAAS,IAAI;AAAA,MAC1E,SAAS,IAAI;AAAA,IACf;AAAA,EACF;AACF;;;APvJO,IAAM,eAAN,MAAM,cAAa;AAAA,EAKxB,YACkB,SACA,MAChB;AAFgB;AACA;AAEhB,SAAK,WAAW,IAAIC,iBAAgB;AAAA,MAClC,WAAW,KAAK;AAAA,MAChB,kBAAkB,KAAK;AAAA,MACvB,eAAe,KAAK;AAAA,IACtB,CAAC;AACD,SAAK,aAAa,IAAI,WAAW,KAAK,SAAS;AAAA,EACjD;AAAA,EAdO;AAAA,EAEC;AAAA,EAcR,aAAa,IAAI,SAAuB,SAAiB;AACvD,UAAM,OAAO,MAAM,QAAQ,QAAQ,oBAAoB,OAAO;AAC9D,UAAM,KAAK,IAAI,cAAa,SAAS,IAAI;AACzC,QAAI,GAAG,YAAY,SAAS;AAC1B,YAAM,IAAI,MAAM,mCAAmC;AAAA,IACrD;AAAA,EACF;AAAA,EAEA,MAAM,aAAmC;AACvC,UAAM,WAAW,MAAM,KAAK,UAAU,eAAe,EAAE,OAAO,KAAK,QAAQ,CAAC;AAC5E,WAAO,QAAQ;AAAA,MACb,SAAS,IAAI,OAAO,YAAgC;AAClD,cAAM,OAAO,MAAM,KAAK,WAAW,YAAY,QAAQ,QAAQ;AAC/D,cAAM,kBAAkB,QAAQ,cAAc,SAC1C,OAAO,QAAQ,YAAY,IAAI,OAAO,QAAQ,cAAc,MAAM,IAClE,OAAO,QAAQ,YAAY;AAE/B,eAAO;AAAA,UACL,MAAMC,oBAAmB,QAAQ,QAAQ;AAAA,UACzC,SAAS,OAAO,eAAe;AAAA,UAC/B,UAAU;AAAA,QACZ;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EAEA,MAAM,aAAa,SAAwD;AACzE,UAAM,0BAA0B;AAAA,MAC9B,QAAQ,CAAC,WAA8B,CAAC,QAAQ,MAAM,MAAM,WAAW,iBAAiB;AAAA,MACxF,GAAG;AAAA,IACL;AACA,WAAO,mBAAmB,KAAK,WAAW,KAAK,SAAS,uBAAuB;AAAA,EACjF;AAAA,EAEA,MAAM,qBAAqD;AACzD,UAAM,MAAM,MAAM,KAAK,QAAQ,uBAAuB,EAAE,cAAc,KAAK,QAAQ,CAAC;AACpF,QAAI,CAAC,IAAI,SAAS;AAChB,aAAO;AAAA,IACT;AAEA,UAAM,YAAY,IAAI;AACtB,UAAM,gBAAgB,IAAI;AAE1B,WAAO;AAAA,MACL,QAAQ,gBAAgB;AAAA,MACxB,WACE,cAAc,UAAU,YACpB,oBAAoB,OAAO,KAAK,OAChC,oBAAoB,OAAO,OAAO;AAAA,MACxC,WAAW,UAAU;AAAA,MACrB,SAAS,UAAU;AAAA,MACnB,QAAQ,UAAU;AAAA,MAClB,WAAW,UAAU;AAAA,MACrB,gBAAgB,UAAU;AAAA,MAC1B,SAAS,UAAU;AAAA,MACnB,OAAO,UAAU;AAAA,MACjB,cAAc,UAAU;AAAA,MACxB,cAAc,eAAe,UAAU;AAAA,MACvC,eAAe,eAAe,WAAW;AAAA,MACzC,aAAa,eAAe,SAAS,CAAC;AAAA,IACxC;AAAA,EACF;AAAA,EAEA,MAAM,mBAAmB,YAAyB;AAChD,WAAO,KAAK,QAAQ,uBAAuB;AAAA,MACzC,cAAc,KAAK;AAAA,MACnB,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,iBAAiB,YAAyB;AAC9C,WAAO,KAAK,QAAQ,oBAAoB,EAAE,cAAc,KAAK,SAAS,GAAG,WAAW,CAAC;AAAA,EACvF;AAAA,EAEA,MAAM,wBAAwB;AAC5B,WAAO,KAAK,QAAQ,yBAAyB,KAAK,OAAO;AAAA,EAC3D;AAAA,EAEA,MAAM,qBAAqB;AACzB,WAAO,KAAK,QAAQ,sBAAsB,KAAK,OAAO;AAAA,EACxD;AAAA,EAEA,MAAM,iBAAiB,OAAqE;AAC1F,UAAM,UAAUC,sBAAqB,wBAAwB;AAAA,MAC3D,cAAc,KAAK;AAAA,MACnB,WAAW,MAAM;AAAA,MACjB,IAAI,MAAM;AAAA,IACZ,CAAC;AACD,UAAM,YAAY,MAAM,KAAK,OAAO,oBAAoB;AAAA,MACtD,YAAY;AAAA,IACd,CAAC;AAED,UAAM,KAAK,QAAQ,iBAAiB;AAAA,MAClC,GAAG;AAAA,MACH,cAAc,KAAK;AAAA,MACnB,WAAW,UAAU;AAAA,IACvB,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,6BAA6B,WAAkC;AACnE,UAAM,KAAK,MAAM,KAAK,mBAAmB;AACzC,WAAO,KAAK,iBAAiB;AAAA,MAC3B,aAAa;AAAA,MACb,QAAQ,gBAAgB;AAAA,MACxB,WAAW,oBAAoB,OAAO,KAAK;AAAA,MAC3C,gBAAgB;AAAA,MAChB;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,+BAA+B,WAAoC;AACvE,UAAM,uBAAuB,KAAK,WAAW,WAAW,KAAK,OAAO;AACpE,UAAM,KAAK,MAAM,KAAK,mBAAmB;AACzC,WAAO,KAAK,iBAAiB;AAAA,MAC3B,aAAa;AAAA,MACb,QAAQ,gBAAgB;AAAA,MACxB,WAAW,oBAAoB,OAAO,OAAO;AAAA,MAC7C,gBAAgB;AAAA,MAChB;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,mBAAmB,QAAgB,SAAiB;AACxD,UAAM,eAAe,gBAAgB,OAAO;AAC5C,UAAM,YAAY,MAAM,KAAK,OAAO,qBAAqB,EAAE,kBAAkB,aAAa,CAAC;AAC3F,WAAO,KAAK,QAAQ,mBAAmB;AAAA,MACrC,cAAc,KAAK;AAAA,MACnB;AAAA,MACA,WAAW,UAAU;AAAA,IACvB,CAAC;AAAA,EACH;AAAA;AAAA;AAAA,EAIA,MAAM,0BAA0B,WAAwB;AACtD,UAAM,MAAM,IAAI,iBAAiB;AACjC,UAAM,UAAU,MAAM,IAAI,MAAM,EAAE,QAAQ,KAAK,UAAU,CAAC;AAC1D,UAAM,SAAS,MAAM,IAAI,UAAU,EAAE,QAAQ,KAAK,UAAU,CAAC;AAC7D,UAAM,YAAY,MAAM,KAAK,OAAO,qBAAqB,EAAE,kBAAkB,QAAQ,CAAC;AACtF,WAAO,KAAK,QAAQ,0BAA0B;AAAA,MAC5C,cAAc,KAAK;AAAA,MACnB,aAAa,MAAM,KAAK,YAAY;AAAA,MACpC;AAAA,MACA;AAAA,MACA,WAAW,UAAU;AAAA,IACvB,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,kBAAkB;AACtB,UAAM,YAAY,MAAM,KAAK,mBAAmB;AAChD,QAAI,CAAC,aAAa,UAAU,iBAAiB,IAAI;AAC/C,YAAM,IAAI,MAAM,kBAAkB;AAAA,IACpC;AAEA,UAAM,kBAAkB,UAAU;AAClC,UAAM,YAAY,eAAe,KAAK,SAAS,eAAe;AAC9D,UAAM,SAAS,MAAM,UAAU,UAAU,EAAE,QAAQ,KAAK,UAAU,CAAC;AACnE,UAAM,UAAU,MAAM,UAAU,MAAM,EAAE,QAAQ,KAAK,UAAU,CAAC;AAChE,UAAM,YAAY,MAAM,KAAK,OAAO,qBAAqB,EAAE,kBAAkB,QAAQ,CAAC;AACtF,WAAO,KAAK,QAAQ,gBAAgB;AAAA,MAClC,cAAc,KAAK;AAAA,MACnB;AAAA,MACA,WAAW,UAAU;AAAA,IACvB,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,oCAAoC;AACxC,WAAO,KAAK,QAAQ,kCAAkC,EAAE,cAAc,KAAK,QAAQ,CAAC;AAAA,EACtF;AAAA,EAEA,MAAM,0BAA0B;AAC9B,WAAO,KAAK,QAAQ,wBAAwB,EAAE,cAAc,KAAK,QAAQ,CAAC;AAAA,EAC5E;AAAA,EAEA,MAAM,oBAA+C;AAEnD,UAAM,MAAM,IAAI,iBAAiB;AACjC,QAAI,UAAU,KAAK,OAAO;AAC1B,QAAI,CAAC,IAAI,UAAU,UAAU,OAAO;AAClC,YAAM,SAAS,MAAM,KAAK,UAAU,qBAAqB;AACzD,UAAI,YAAY,MAAM;AAAA,IACxB;AACA,UAAM,UAAU,MAAM,IAAI,MAAM,EAAE,QAAQ,KAAK,UAAU,CAAC;AAC1D,UAAM,eAAe,MAAM,KAAK,UAAU,uBAAuB,EAAE,kBAAkB,QAAQ,CAAC;AAE9F,UAAM,UAAU,aAAa,QAAQ,OAAO,WAAW;AACvD,UAAM,WAAW,aAAa,QAAQ,OAAO;AAC7C,UAAM,WAAW,OAAO,IAAI,UAAU,UAAU,KAAe;AAC/D,UAAM,EAAE,QAAQ,IAAI,aAAa;AAEjC,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,iBAAiB,SAAoB;AACzC,QAAI;AACJ,QAAI;AACJ,QAAI,QAAQ,MAAM,UAAU,KAAK,KAAK,WAAW;AAC/C,gBAAU,IAAI,IAAI,QAAQ,MAAM,IAAI,CAAC,SAAS,CAAC,KAAK,aAAa,KAAK,SAAS,CAAC,CAAC;AACjF,gBAAU,QAAQ;AAAA,IACpB,WAAW,QAAQ,eAAe,QAAQ,iBAAiB,QAAQ,aAAa,UAAU,KAAK,KAAK,WAAW;AAC7G,gBAAU,IAAI,IAAI,QAAQ,YAAY,IAAI,CAAC,SAAS,CAAC,KAAK,aAAa,KAAK,SAAS,CAAC,CAAC;AACvF,gBAAU,QAAQ;AAAA,IACpB,OAAO;AACL,YAAM,IAAI,MAAM,uBAAuB;AAAA,IACzC;AAEA,UAAM,OAA8B,CAAC;AACrC,aAAS,IAAI,GAAG,IAAI,KAAK,KAAK,OAAO,QAAQ,KAAK;AAChD,YAAM,QAAQ,KAAK,KAAK,OAAO,CAAC;AAChC,YAAM,YAAY,QAAQ,IAAI,MAAM,OAAO;AAC3C,UAAI,WAAW;AACb,aAAK,KAAK,SAAS;AAAA,MACrB;AAAA,IACF;AACA,UAAM,iBAAiB,KAAK,SAAS,yBAAyB,IAAI;AAClE,WAAO,KAAK,UAAU,wBAAwB;AAAA,MAC5C,kBAAkB,gBAAgB,OAAO;AAAA,MACzC,WAAW;AAAA,MACX,SAAS,EAAE,aAAa,KAAK;AAAA,IAC/B,CAAC;AAAA,EACH;AAAA,EAEA,IAAI,UAAU;AACZ,WAAO,KAAK,SAAS;AAAA,EACvB;AAAA,EAEA,IAAY,UAAU;AACpB,WAAO,KAAK,QAAQ;AAAA,EACtB;AAAA,EAEA,IAAY,SAAS;AACnB,WAAO,KAAK,QAAQ;AAAA,EACtB;AAAA,EAEA,MAAc,cAAc;AAC1B,WAAO,KAAK,QAAQ,OAAO,QAAQ;AAAA,EACrC;AAAA,EAEA,IAAY,YAAY;AACtB,WAAO,KAAK,QAAQ;AAAA,EACtB;AACF;;;AQ1RO,IAAM,kBAAN,MAAsB;AAAA,EAG3B,YAA4B,SAAuB;AAAvB;AAC1B,SAAK,kBAAkB,oBAAI,IAAuB;AAAA,EACpD;AAAA,EAJQ;AAAA,EAMR,MAAM,aAAa,SAAiB;AAClC,UAAM,SAAS,KAAK,gBAAgB,IAAI,OAAO;AAC/C,QAAI,QAAQ;AACV,aAAO;AAAA,IACT;AACA,UAAM,KAAK,MAAM,KAAK,cAAc,OAAO;AAC3C,QAAI,IAAI;AACN,WAAK,gBAAgB,IAAI,SAAS,EAAE;AAAA,IACtC;AACA,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,kBAAkB,WAAyD;AAC/E,UAAM,UAAqC,IAAI,MAAM,UAAU,MAAM,EAAE,KAAK,MAAS;AAGrF,aAAS,IAAI,GAAG,IAAI,UAAU,QAAQ,KAAK;AACzC,YAAM,UAAU,UAAU,CAAC;AAC3B,cAAQ,CAAC,IAAI,KAAK,gBAAgB,IAAI,OAAO;AAAA,IAC/C;AAGA,UAAM,eAAe,QAClB,IAAI,CAAC,MAAM,UAAW,SAAS,SAAY,QAAQ,EAAG,EACtD,OAAO,CAAC,UAAU,UAAU,EAAE;AACjC,QAAI,aAAa,WAAW,GAAG;AAC7B,aAAO;AAAA,IACT;AACA,UAAM,gBAAgB,MAAM,KAAK,QAAQ,QAAQ,kBAAkB,aAAa,IAAI,CAAC,UAAU,UAAU,KAAK,CAAC,CAAC;AAChH,aAAS,IAAI,GAAG,IAAI,aAAa,QAAQ,KAAK;AAC5C,YAAM,QAAQ,aAAa,CAAC;AAC5B,cAAQ,KAAK,IAAI,cAAc,CAAC;AAAA,IAClC;AAGA,aAAS,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;AACvC,UAAI,QAAQ,CAAC,MAAM,QAAW;AAC5B,gBAAQ,CAAC,IAAI,MAAM,KAAK,sBAAsB,UAAU,CAAC,CAAC;AAAA,MAC5D;AAAA,IACF;AAGA,aAAS,IAAI,GAAG,IAAI,UAAU,QAAQ,KAAK;AACzC,UAAI,QAAQ,CAAC,GAAG;AACd,aAAK,gBAAgB,IAAI,UAAU,CAAC,GAAG,QAAQ,CAAC,CAAc;AAAA,MAChE;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA,EAEA,MAAc,cAAc,SAAiB;AAC3C,UAAM,YAAY,MAAM,KAAK,wBAAwB,OAAO;AAC5D,QAAI,WAAW;AACb,aAAO;AAAA,IACT;AACA,UAAM,UAAU,MAAM,KAAK,sBAAsB,OAAO;AACxD,QAAI,SAAS;AACX,aAAO;AAAA,IACT;AACA,WAAO;AAAA,EACT;AAAA,EAEA,MAAc,wBAAwB,SAAiD;AACrF,QAAI;AACF,YAAM,KAAK,MAAM,KAAK,QAAQ,QAAQ,aAAa,OAAO;AAC1D,aAAO;AAAA,IACT,SAAS,GAAG;AACV,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEA,MAAc,sBAAsB,SAAiD;AACnF,WAAO,sBAAsB,KAAK,QAAQ,WAAW,OAAO;AAAA,EAC9D;AACF;;;AC1FA,SAAS,iBAAiB;;;ACA1B;AAAA,EA0BE,kBAAAC;AAAA,EAGA;AAAA,OACK;AAGP,OAAO,WAAW;AAIX,IAAM,cAAN,MAAM,aAAgC;AAAA,EAG3C,YAA6B,QAAgB;AAAhB;AAAA,EAAiB;AAAA,EAFtC;AAAA,EAIR,MAAM,SAAS,OAAyC;AACtD,UAAM,MAAM,MAAM,MAAM,KAAqB,GAAG,KAAK,MAAM,eAAe,KAAK;AAE/E,QAAI,IAAI,WAAW,OAAO,IAAI,WAAW,KAAK;AAC5C,YAAM,IAAI,MAAM,4BAA4B,GAAG,EAAE;AAAA,IACnD;AACA,SAAK,SAAS,IAAI,KAAK;AACvB,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,MAAM,YAAY,KAAiC;AACjD,QAAI;AACF,YAAM,MAAM,MAAM,MAAM,IAAI,GAAG,KAAK,MAAM,SAAS,EAAE,SAAS,KAAK,QAAQ,GAAG,EAAE,CAAC;AACjF,aAAO,IAAI,WAAW;AAAA,IACxB,SAAS,GAAG;AACV,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEA,YAAY,OAAiB;AAC3B,SAAK,SAAS;AAAA,EAChB;AAAA,EAEA,MAAM,aAAa,SAAiD;AAClE,YAAQ,MAAM,KAAK,kBAAkB,CAAC,OAAO,CAAC,GAAG,CAAC;AAAA,EACpD;AAAA,EAEA,MAAM,kBAAkB,WAAyD;AAC/E,UAAM,QAAiC;AAAA,MACrC,iBAAiB;AAAA,IACnB;AACA,UAAM,MAAM,MAAM,MAAM,IAA4B,GAAG,KAAK,MAAM,qBAAqB;AAAA,MACrF,QAAQ;AAAA,MACR,SAAS,KAAK,QAAQ;AAAA,IACxB,CAAC;AAGD,QAAI,IAAI,WAAW,OAAO,IAAI,WAAW,KAAK;AAC5C,YAAM,IAAI,MAAM,qCAAqC,GAAG,EAAE;AAAA,IAC5D;AACA,WAAO,IAAI,MAAM;AAAA,MAAI,CAAC,wBACpB,sBAAsBA,gBAAe,GAAG,mBAAmB,IAAI;AAAA,IACjE;AAAA,EACF;AAAA,EAEA,MAAM,oBAAoB,cAA6C;AACrE,UAAM,IAAoB;AAAA,MACxB;AAAA,IACF;AACA,UAAM,MAAM,MAAM,MAAM,IAAoB,GAAG,KAAK,MAAM,UAAU;AAAA,MAClE,QAAQ;AAAA,MACR,SAAS,KAAK,QAAQ;AAAA,IACxB,CAAC;AAED,QAAI,IAAI,WAAW,OAAO,IAAI,WAAW,KAAK;AAC5C,YAAM,IAAI,MAAM,qCAAqC,GAAG,EAAE;AAAA,IAC5D;AACA,WAAO,aAAY,cAAc,IAAI,IAAI;AAAA,EAC3C;AAAA,EAEA,MAAM,cAAsC;AAC1C,UAAM,UAAU,MAAM,MAAM,IAAmB,GAAG,KAAK,MAAM,SAAS;AAAA,MACpE,SAAS,KAAK,QAAQ;AAAA,IACxB,CAAC;AAED,QAAI,QAAQ,WAAW,OAAO,QAAQ,WAAW,KAAK;AACpD,YAAM,IAAI,MAAM,qCAAqC,OAAO,EAAE;AAAA,IAChE;AACA,WAAO,QAAQ;AAAA,EACjB;AAAA,EAEA,MAAM,sBAAsB,OAGY;AACtC,UAAM,IAAqB;AAAA,MACzB,QAAQ,MAAM,UAAU,gBAAgB;AAAA,MACxC,GAAI,MAAM,aACN;AAAA,QACE,MAAM,MAAM,WAAW,KAAK,SAAS;AAAA,QACrC,OAAO,MAAM,WAAW,MAAM,SAAS;AAAA,MACzC,IACA,CAAC;AAAA,IACP;AACA,UAAM,MAAM,MAAM,MAAM,IAAkC,GAAG,KAAK,MAAM,gBAAgB;AAAA,MACtF,QAAQ;AAAA,MACR,SAAS,KAAK,QAAQ;AAAA,IACxB,CAAC;AACD,QAAI,IAAI,WAAW,OAAO,IAAI,WAAW,KAAK;AAC5C,YAAM,IAAI,MAAM,yCAAyC,GAAG,EAAE;AAAA,IAChE;AACA,WAAO;AAAA,MACL,MAAM,IAAI,KAAK,KAAK,IAAI,aAAY,aAAa;AAAA,MACjD,MAAM,IAAI,KAAK;AAAA,IACjB;AAAA,EACF;AAAA,EAEA,MAAM,kBAAkB,OAAyE;AAC/F,UAAM,IAA2B;AACjC,UAAM,MAAM,MAAM,MAAM,KAAK,GAAG,KAAK,MAAM,iBAAiB,GAAG,EAAE,SAAS,KAAK,QAAQ,EAAE,CAAC;AAC1F,QAAI,IAAI,WAAW,OAAO,IAAI,WAAW,KAAK;AAC5C,YAAM,IAAI,MAAM,qCAAqC,GAAG,EAAE;AAAA,IAC5D;AAAA,EACF;AAAA,EAEA,MAAM,uBAAuB,OAA8E;AACzG,UAAM,MAAM,MAAM,MAAM,IAAmC,GAAG,KAAK,MAAM,wBAAwB;AAAA,MAC/F,QAAQ;AAAA,MACR,SAAS,KAAK,QAAQ;AAAA,IACxB,CAAC;AACD,QAAI,IAAI,WAAW,OAAO,IAAI,WAAW,KAAK;AAC5C,YAAM,IAAI,MAAM,qCAAqC,GAAG,EAAE;AAAA,IAC5D;AACA,WAAO,IAAI;AAAA,EACb;AAAA,EAEA,MAAM,uBAAuB,OAAgF;AAC3G,UAAM,MAAM,MAAM,MAAM,IAAoC,GAAG,KAAK,MAAM,wBAAwB;AAAA,MAChG,QAAQ;AAAA,MACR,SAAS,KAAK,QAAQ;AAAA,IACxB,CAAC;AACD,QAAI,IAAI,WAAW,OAAO,IAAI,WAAW,KAAK;AAC5C,YAAM,IAAI,MAAM,4CAA4C,GAAG,EAAE;AAAA,IACnE;AACA,WAAO,IAAI;AAAA,EACb;AAAA,EAEA,MAAM,oBAAoB,OAAyE;AACjG,UAAM,MAAM,MAAM,MAAM,IAAsC,GAAG,KAAK,MAAM,0BAA0B;AAAA,MACpG,QAAQ;AAAA,MACR,SAAS,KAAK,QAAQ;AAAA,IACxB,CAAC;AACD,QAAI,IAAI,WAAW,OAAO,IAAI,WAAW,KAAK;AAC5C,YAAM,IAAI,MAAM,4CAA4C,GAAG,EAAE;AAAA,IACnE;AACA,WAAO,IAAI;AAAA,EACb;AAAA,EAEA,MAAM,yBAAyB,SAAkC;AAC/D,UAAM,MAAM,MAAM,MAAM,IAAY,GAAG,KAAK,MAAM,2BAA2B;AAAA,MAC3E,QAAQ;AAAA,QACN,cAAc;AAAA,MAChB;AAAA,MACA,SAAS,KAAK,QAAQ;AAAA,IACxB,CAAC;AACD,QAAI,IAAI,WAAW,OAAO,IAAI,WAAW,KAAK;AAC5C,YAAM,IAAI,MAAM,4CAA4C,GAAG,EAAE;AAAA,IACnE;AACA,WAAO,IAAI;AAAA,EACb;AAAA,EAEA,MAAM,sBAAsB,SAAkC;AAC5D,UAAM,MAAM,MAAM,MAAM,IAAY,GAAG,KAAK,MAAM,wBAAwB;AAAA,MACxE,QAAQ;AAAA,QACN,cAAc;AAAA,MAChB;AAAA,MACA,SAAS,KAAK,QAAQ;AAAA,IACxB,CAAC;AACD,QAAI,IAAI,WAAW,OAAO,IAAI,WAAW,KAAK;AAC5C,YAAM,IAAI,MAAM,yCAAyC,GAAG,EAAE;AAAA,IAChE;AACA,WAAO,IAAI;AAAA,EACb;AAAA,EAEA,MAAM,mBAAmB,OAAuC;AAC9D,UAAM,MAAM,MAAM,MAAM,KAAK,GAAG,KAAK,MAAM,iBAAiB,OAAO;AAAA,MACjE,SAAS,KAAK,QAAQ;AAAA,IACxB,CAAC;AACD,QAAI,IAAI,WAAW,OAAO,IAAI,WAAW,KAAK;AAC5C,YAAM,IAAI,MAAM,sCAAsC,GAAG,EAAE;AAAA,IAC7D;AAAA,EACF;AAAA,EAEA,MAAM,iBAAiB,OAAgD;AACrE,UAAM,MAAM,MAAM,MAAM,KAAK,GAAG,KAAK,MAAM,0BAA0B,OAAO,EAAE,SAAS,KAAK,QAAQ,EAAE,CAAC;AACvG,QAAI,IAAI,WAAW,OAAO,IAAI,WAAW,KAAK;AAC5C,YAAM,IAAI,MAAM,oCAAoC,GAAG,EAAE;AAAA,IAC3D;AAAA,EACF;AAAA;AAAA;AAAA,EAIA,MAAM,0BAA0B,QAMd;AAChB,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,gBAAgB,OAAgC;AACpD,UAAM,MAAM,MAAM,MAAM,KAAK,GAAG,KAAK,MAAM,+BAA+B,OAAO;AAAA,MAC/E,SAAS,KAAK,QAAQ;AAAA,IACxB,CAAC;AACD,QAAI,IAAI,WAAW,OAAO,IAAI,WAAW,KAAK;AAC5C,YAAM,IAAI,MAAM,sCAAsC,GAAG,EAAE;AAAA,IAC7D;AAAA,EACF;AAAA,EAEA,MAAM,mBAAmB,OAAgC;AACvD,UAAM,MAAM,MAAM,MAAM,KAAK,GAAG,KAAK,MAAM,6BAA6B,OAAO;AAAA,MAC7E,SAAS,KAAK,QAAQ;AAAA,IACxB,CAAC;AACD,QAAI,IAAI,WAAW,OAAO,IAAI,WAAW,KAAK;AAC5C,YAAM,IAAI,MAAM,sCAAsC,GAAG,EAAE;AAAA,IAC7D;AAAA,EACF;AAAA,EAEA,MAAM,kCAAkC,OAAiC;AACvE,UAAM,MAAM,MAAM,MAAM,KAAK,GAAG,KAAK,MAAM,8BAA8B,OAAO,EAAE,SAAS,KAAK,QAAQ,EAAE,CAAC;AAC3G,QAAI,IAAI,WAAW,OAAO,IAAI,WAAW,KAAK;AAC5C,YAAM,IAAI,MAAM,qDAAqD,GAAG,EAAE;AAAA,IAC5E;AAAA,EACF;AAAA,EAEA,MAAM,wBAAwB,OAA8B;AAC1D,UAAM,MAAM,MAAM,MAAM,KAAK,GAAG,KAAK,MAAM,6BAA6B,OAAO,EAAE,SAAS,KAAK,QAAQ,EAAE,CAAC;AAC1G,QAAI,IAAI,WAAW,OAAO,IAAI,WAAW,KAAK;AAC5C,YAAM,IAAI,MAAM,2CAA2C,GAAG,EAAE;AAAA,IAClE;AAAA,EACF;AAAA,EAEA,MAAM,sBAAsB,YAA2D;AACrF,UAAM,MAAM,MAAM,MAAM,IAA2B,GAAG,KAAK,MAAM,iBAAiB;AAAA,MAChF,SAAS,KAAK,QAAQ;AAAA,MACtB,QAAQ;AAAA,IACV,CAAC;AACD,QAAI,IAAI,WAAW,KAAK;AACtB,YAAM,IAAI,MAAM,gCAAgC,GAAG,EAAE;AAAA,IACvD;AACA,WAAO,IAAI;AAAA,EACb;AAAA,EAEA,MAAM,kBAAkB,OAA8E;AACpG,UAAM,MAAM,MAAM,MAAM,KAAK,GAAG,KAAK,MAAM,iBAAiB,OAAO,EAAE,SAAS,KAAK,QAAQ,EAAE,CAAC;AAC9F,QAAI,IAAI,WAAW,OAAO,IAAI,WAAW,KAAK;AAC5C,YAAM,IAAI,MAAM,qCAAqC,GAAG,EAAE;AAAA,IAC5D;AAAA,EACF;AAAA;AAAA,EAGA,MAAM,2BAA2B,SAAiB;AAChD,WAAO;AAAA,EACT;AAAA,EAEQ,QAAQ,OAAgB;AAC9B,WAAO,EAAE,eAAe,UAAU,SAAS,KAAK,MAAM,GAAG;AAAA,EAC3D;AAAA,EAEA,OAAe,cAAc,MAAoC;AAC/D,WAAO;AAAA,MACL,GAAG;AAAA,MACH,QAAQ,KAAK,OAAO,IAAI,CAAC,WAAW;AAAA,QAClC,SAAS,MAAM;AAAA,QACf,QAAQ,MAAM;AAAA,QACd,WAAWA,gBAAe,GAAG;AAAA,UAC3B,kBAAkB,MAAM;AAAA,UACxB,QAAQ,MAAM;AAAA,QAChB,CAAC;AAAA,MACH,EAAE;AAAA,IACJ;AAAA,EACF;AACF;;;AClTO,IAAK,WAAL,kBAAKC,cAAL;AACL,EAAAA,UAAA,WAAQ;AACR,EAAAA,UAAA,UAAO;AACP,EAAAA,UAAA,SAAM;AACN,EAAAA,UAAA,UAAO;AACP,EAAAA,UAAA,UAAO;AALG,SAAAA;AAAA,GAAA;AA0BL,IAAM,oBAAoB;AAE1B,IAAM,kBAAkB;AACxB,IAAM,kBAAkB;AAExB,IAAM,gBAAgB;AACtB,IAAM,oBAAoB;AAE1B,IAAM,cAAc;AACpB,IAAM,kBAAkB;AAExB,IAAM,cAAc,oBAAI,IAA2B;AAAA,EACxD;AAAA,IACE;AAAA,IACA;AAAA,MACE,WAAW;AAAA,QACT,KAAK;AAAA,MACP;AAAA,MACA,SAAS;AAAA,QACP,KAAK;AAAA,MACP;AAAA,MACA,YAAY;AAAA,IACd;AAAA,EACF;AAAA,EACA;AAAA,IACE;AAAA,IACA;AAAA,MACE,WAAW;AAAA,QACT,KAAK;AAAA,MACP;AAAA,MACA,SAAS;AAAA,QACP,KAAK;AAAA,MACP;AAAA,MACA,YAAY;AAAA,IACd;AAAA,EACF;AAAA,EACA;AAAA,IACE;AAAA,IACA;AAAA,MACE,WAAW;AAAA,QACT,KAAK;AAAA,MACP;AAAA,MACA,SAAS;AAAA,QACP,KAAK;AAAA,MACP;AAAA,MACA,YAAY;AAAA,IACd;AAAA,EACF;AACF,CAAC;AAEM,SAAS,eAAe,KAAe,SAA8B;AAC1E,QAAM,SAAS,YAAY,IAAI,GAAG;AAClC,MAAI,CAAC,QAAQ;AACX,UAAM,IAAI,MAAM,qBAAqB;AAAA,EACvC;AACA,MAAI,SAAS,WAAW,KAAK;AAC3B,WAAO,UAAU,MAAM,QAAQ,UAAU;AAAA,EAC3C;AACA,MAAI,SAAS,SAAS,KAAK;AACzB,WAAO,QAAQ,MAAM,QAAQ,QAAQ;AAAA,EACvC;AACA,SAAO;AACT;;;AFjFO,IAAM,eAAN,MAAM,cAAa;AAAA,EACR;AAAA,EAEA;AAAA,EAEA;AAAA,EAEhB;AAAA,EAEA,YAAY,OAAyE;AACnF,SAAK,UAAU,MAAM;AACrB,SAAK,YAAY,MAAM;AACvB,SAAK,SAAS,MAAM;AAAA,EACtB;AAAA,EAEA,aAAa,IAAI,KAAe,SAA8B;AAC5D,UAAM,SAAS,eAAe,KAAK,OAAO;AAC1C,UAAM,YAAY,IAAI,UAAU,OAAO,SAAS;AAChD,UAAM,UAAU,IAAI,YAAY,OAAO,QAAQ,GAAG;AAClD,WAAO,IAAI,cAAa;AAAA,MACtB;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,cAAc,QAAiB;AAC7B,SAAK,UAAU;AAAA,EACjB;AAAA,EAEA,IAAI,SAAS;AACX,QAAI,CAAC,KAAK,SAAS;AACjB,YAAM,IAAI,MAAM,sBAAsB;AAAA,IACxC;AACA,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,IAAI,OAAO,KAAc;AACvB,SAAK,UAAU;AAAA,EACjB;AACF;;;AZ5BO,IAAM,cAAN,MAAM,aAAY;AAAA,EAKvB,YAA4B,SAAuB;AAAvB;AAAA,EAAwB;AAAA,EAJ5C;AAAA,EAEA;AAAA,EAIR,aAAa,IAAI,KAAe,SAA8B;AAC5D,UAAM,UAAU,MAAM,aAAa,IAAI,KAAK,OAAO;AACnD,WAAO,IAAI,aAAY,OAAO;AAAA,EAChC;AAAA,EAEA,MAAM,cAAc,OAAoE;AACtF,QAAI,MAAM,UAAU;AAClB,YAAM,WAAW,MAAM,KAAK,QAAQ,YAAY,MAAM,QAAQ;AAC9D,UAAI,UAAU;AACZ,aAAK,QAAQ,SAAS,MAAM;AAC5B,aAAK,QAAQ,YAAY,MAAM,QAAQ;AACvC,eAAO,MAAM;AAAA,MACf;AAAA,IACF;AACA,UAAM,MAAM,MAAM,KAAK,SAAS,MAAM,MAAM;AAC5C,SAAK,QAAQ,SAAS,MAAM;AAC5B,SAAK,QAAQ,YAAY,GAAG;AAC5B,WAAO;AAAA,EACT;AAAA,EAEA,MAAc,SAAS,QAAoC;AACzD,UAAM,aAAaC,sBAAqB,2BAA0B,oBAAI,KAAK,GAAE,YAAY,CAAC;AAC1F,UAAM,MAAM,MAAM,OAAO,oBAAoB;AAAA,MAC3C;AAAA,IACF,CAAC;AACD,WAAO,KAAK,QAAQ,SAAS;AAAA,MAC3B,SAAS,MAAM,OAAO,QAAQ;AAAA,MAC9B,SAAS;AAAA,MACT,WAAW,IAAI;AAAA,MACf,YAAY,OAAO;AAAA,IACrB,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,WAAW;AACf,WAAO,KAAK,QAAQ,QAAQ,YAAY;AAAA,EAC1C;AAAA,EAEA,MAAM,WAAW,YAAgE;AAC/E,WAAO,KAAK,QAAQ,QAAQ,sBAAsB,EAAE,QAAQC,iBAAgB,QAAQ,WAAW,CAAC;AAAA,EAClG;AAAA,EAEA,MAAM,cAAc,MAAuB;AACzC,WAAO,KAAK,eAAe,oBAAoB,IAAI;AAAA,EACrD;AAAA,EAEA,gBAAgB,MAAoB;AAClC,WAAO,IAAI,aAAa,KAAK,SAAS,IAAI;AAAA,EAC5C;AAAA,EAEA,MAAM,2BAA2B,cAAsB;AACrD,UAAM,OAAO,MAAM,KAAK,QAAQ,oBAAoB,YAAY;AAChE,WAAO,IAAI,aAAa,KAAK,SAAS,IAAI;AAAA,EAC5C;AAAA;AAAA;AAAA,EAIA,IAAI,iBAAiB;AACnB,QAAI,CAAC,KAAK,iBAAiB;AACzB,WAAK,kBAAkB,IAAI,aAAa,KAAK,SAAS,KAAK,eAAe;AAAA,IAC5E;AACA,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,IAAI,kBAAkB;AACpB,QAAI,CAAC,KAAK,kBAAkB;AAC1B,WAAK,mBAAmB,IAAI,gBAAgB,KAAK,OAAO;AAAA,IAC1D;AACA,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,IAAI,SAAS;AACX,WAAO,KAAK,QAAQ;AAAA,EACtB;AAAA,EAEA,IAAI,UAAU;AACZ,WAAO,KAAK,QAAQ;AAAA,EACtB;AAAA,EAEA,IAAI,SAAS;AACX,WAAO,KAAK,QAAQ;AAAA,EACtB;AAAA,EAEA,IAAI,cAA8B;AAChC,WAAO,IAAI,eAAe,KAAK,OAAO;AAAA,EACxC;AAAA,EAEA,IAAI,aAA4B;AAC9B,WAAO,IAAI,cAAc,KAAK,OAAO;AAAA,EACvC;AAAA,EAEA,MAAc,gBAAgB;AAC5B,WAAO,KAAK,OAAO,QAAQ;AAAA,EAC7B;AACF;","names":["SigningMessageHelper","UserMSafeStatus","SigningMessageHelper","MultiSigAccount","SigningMessageHelper","normalizeStructTag","normalizeStructTag","normalizeStructTag","PublicKeySerde","PublicKeySerde","MultiSigAccount","normalizeStructTag","SigningMessageHelper","PublicKeySerde","MSafeEnv","SigningMessageHelper","UserMSafeStatus"]}
1
+ {"version":3,"sources":["../src/core/CreateHelper.ts","../src/core/MSafeClient.ts","../src/core/AddressBookSDK.ts","../src/core/InvitationSDK.ts","../src/core/MSafeAccount.ts","../src/utils/buffer.ts","../src/utils/crypto.ts","../src/utils/format.ts","../src/utils/coin.ts","../src/utils/sui.ts","../src/utils/iter/iterator.ts","../src/utils/iter/object.ts","../src/core/PublicKeyHelper.ts","../src/globals/MSafeGlobals.ts","../src/backend/BackendImpl.ts","../src/globals/const.ts"],"sourcesContent":["import { MultiSigAccount, MultiSigConfig, PublicKeySerde, SigningMessageHelper } from '@msafe/sui3-utils';\nimport { PublicKey, SerializedSignature } from '@mysten/sui.js/cryptography';\n\nimport { PublicKeyHelper } from '@/core/PublicKeyHelper';\nimport { MSafeGlobals } from '@/globals/MSafeGlobals';\nimport { CreateMSafeInfo } from '@/types';\n\nexport class CreateHelper {\n constructor(\n public readonly globals: MSafeGlobals,\n public readonly pkHelper: PublicKeyHelper,\n ) {}\n\n async getPublicKeyBatch(addresses: string[]) {\n return this.pkHelper.getPublicKeyBatch(addresses);\n }\n\n async calculateMSafeAddress(info: CreateMSafeInfo) {\n const msConfig = await this.reduceCreationInfoToRawConfig(info);\n const ms = new MultiSigAccount(msConfig);\n return ms.address;\n }\n\n // Validate the create info and return the msafe address.\n async validateCreateInfo(createInfo: CreateMSafeInfo) {\n // Calculate the sui address will check the multi-sig\n return this.calculateMSafeAddress(createInfo);\n }\n\n async submitMSafeCreation(creationInfo: CreateMSafeInfo) {\n const msafeAddress = await this.validateCreateInfo(creationInfo);\n\n const signingMessage = SigningMessageHelper.createMSafeMessage(msafeAddress);\n const signature = await this.globals.wallet.signPersonalMessage({ messageStr: signingMessage });\n\n await this.submitToBackend(creationInfo, signature.signature);\n return msafeAddress;\n }\n\n private async reduceCreationInfoToRawConfig(info: CreateMSafeInfo): Promise<MultiSigConfig> {\n const publicKeys = await this.getPublicKeyBatch(info.owners.map((owner) => owner.address));\n publicKeys.forEach((pk, i) => {\n if (pk === undefined) {\n throw new Error(`Unknown public key for address: ${info.owners[i].address}`);\n }\n });\n return {\n threshold: info.threshold,\n ownersWithWeight: info.owners.map((owner, i) => ({\n publicKey: publicKeys[i] as PublicKey,\n weight: owner.weight,\n })),\n creationNonce: info.creationNonce,\n };\n }\n\n private async submitToBackend(createInfo: CreateMSafeInfo, signature: SerializedSignature) {\n const pks = await this.pkHelper.getPublicKeyBatch(createInfo.owners.map((owner) => owner.address));\n await this.globals.backend.createMSafeAccount({\n owners: createInfo.owners.map((owner, i) => ({\n address: owner.address,\n weight: owner.weight,\n ...PublicKeySerde.ser(pks[i] as PublicKey),\n })),\n threshold: createInfo.threshold,\n name: createInfo.name, // name validation is deferred to backend\n description: createInfo.description, // description validation is deferred to backend\n creationNonce: createInfo.creationNonce,\n signature,\n });\n }\n}\n","import {\n IMSafeConfig,\n IPagedResult,\n IPageOptions,\n JWTToken,\n SigningMessageHelper,\n UserMSafeStatus,\n} from '@msafe/sui3-utils';\n\nimport { AddressBookSDK } from '@/core/AddressBookSDK';\nimport { CreateHelper } from '@/core/CreateHelper';\nimport { InvitationSDK } from '@/core/InvitationSDK';\nimport { MSafeAccount } from '@/core/MSafeAccount';\nimport { PublicKeyHelper } from '@/core/PublicKeyHelper';\nimport { MSafeConfigOptions, MSafeEnv } from '@/globals/const';\nimport { MSafeGlobals } from '@/globals/MSafeGlobals';\nimport { CreateMSafeInfo } from '@/types';\nimport { IWallet } from '@/types/wallet';\n\nexport class MSafeClient {\n private _creationHelper: CreateHelper | undefined;\n\n private _publicKeyHelper: PublicKeyHelper | undefined;\n\n constructor(public readonly globals: MSafeGlobals) {}\n\n static async New(env: MSafeEnv, options?: MSafeConfigOptions) {\n const globals = await MSafeGlobals.New(env, options);\n return new MSafeClient(globals);\n }\n\n async connectWallet(input: { wallet: IWallet; jwtToken?: JWTToken }): Promise<JWTToken> {\n if (input.jwtToken) {\n const verified = await this.backend.verifyToken(input.jwtToken);\n if (verified) {\n this.globals.wallet = input.wallet;\n this.backend.setJWTToken(input.jwtToken);\n return input.jwtToken;\n }\n }\n const jwt = await this.authSign(input.wallet);\n this.globals.wallet = input.wallet;\n this.backend.setJWTToken(jwt);\n return jwt;\n }\n\n private async authSign(wallet: IWallet): Promise<JWTToken> {\n const messageStr = SigningMessageHelper.loginMessageWithTimestamp(new Date().toUTCString());\n const sig = await wallet.signPersonalMessage({\n messageStr,\n });\n return this.backend.authSign({\n address: await wallet.address(),\n message: messageStr,\n signature: sig.signature,\n walletType: wallet.walletType,\n });\n }\n\n async userInfo() {\n return this.globals.backend.getUserInfo();\n }\n\n async ownedMSafe(pagination?: IPageOptions): Promise<IPagedResult<IMSafeConfig>> {\n return this.globals.backend.getOwnedMSafeByStatus({ status: UserMSafeStatus.active, pagination });\n }\n\n async createAccount(info: CreateMSafeInfo) {\n return this.creationHelper.submitMSafeCreation(info);\n }\n\n getMSafeAccount(info: IMSafeConfig) {\n return new MSafeAccount(this.globals, info);\n }\n\n async getMSafeAccountFromAddress(msafeAddress: string) {\n const info = await this.backend.getMSafeAccountInfo(msafeAddress);\n return new MSafeAccount(this.globals, info);\n }\n\n // Get the creation helper to calculate the msafe account address,\n // validation, and more.\n get creationHelper() {\n if (!this._creationHelper) {\n this._creationHelper = new CreateHelper(this.globals, this.publicKeyHelper);\n }\n return this._creationHelper;\n }\n\n get publicKeyHelper() {\n if (!this._publicKeyHelper) {\n this._publicKeyHelper = new PublicKeyHelper(this.globals);\n }\n return this._publicKeyHelper;\n }\n\n get config() {\n return this.globals.config;\n }\n\n get backend() {\n return this.globals.backend;\n }\n\n get wallet() {\n return this.globals.wallet;\n }\n\n get AddressBook(): AddressBookSDK {\n return new AddressBookSDK(this.globals);\n }\n\n get Invitation(): InvitationSDK {\n return new InvitationSDK(this.globals);\n }\n\n private async walletAddress() {\n return this.wallet.address();\n }\n}\n","import { IPageOptions, SigningMessageHelper, UpdateAddressBookEntry } from '@msafe/sui3-utils';\n\nimport { MSafeGlobals } from '@/globals';\n\nexport class AddressBookSDK {\n constructor(public readonly globals: MSafeGlobals) {}\n\n async getEntries(pagination?: IPageOptions) {\n return this.globals.backend.getAddressBookEntries(pagination);\n }\n\n async update(updates: UpdateAddressBookEntry[]) {\n const messageStr = SigningMessageHelper.updateAddressBookMessage(updates);\n const sig = await this.globals.wallet.signPersonalMessage({ messageStr });\n return this.globals.backend.updateAddressBook({ updates, signature: sig.signature });\n }\n}\n","import { IMSafeConfig, IPagedResult, IPageOptions, UserMSafeStatus } from '@msafe/sui3-utils';\n\nimport { MSafeGlobals } from '@/globals';\n\nexport class InvitationSDK {\n constructor(public readonly globals: MSafeGlobals) {}\n\n async getMSafeByStatus(status: UserMSafeStatus, pagination?: IPageOptions): Promise<IPagedResult<IMSafeConfig>> {\n return this.globals.backend.getOwnedMSafeByStatus({ status, pagination });\n }\n\n async updateMSafeStatus(msafeAddress: string, status: UserMSafeStatus) {\n return this.globals.backend.updateMSafeStatus({ msafeAddress, status });\n }\n}\n","import {\n CoinTransferIntention,\n IMSafeConfig,\n IProposeIntentionRequest,\n MultiSigAccount,\n ObjectTransferIntention,\n SigningMessageHelper,\n TransactionDefaultApplication,\n TransactionSubTypes,\n TransactionType,\n TxIntention,\n buildObjectTransferTxb,\n buildRejectTxb,\n isSameAddress,\n} from '@msafe/sui3-utils';\nimport { SuiObjectData } from '@mysten/sui.js/client';\nimport { SerializedSignature } from '@mysten/sui.js/cryptography';\nimport { SuiObjectResponse } from '@mysten/sui.js/src/client';\nimport { TransactionBlock } from '@mysten/sui.js/transactions';\nimport { normalizeStructTag } from '@mysten/sui.js/utils';\n\nimport { MSafeGlobals } from '@/globals/MSafeGlobals';\nimport { OwnedCoin } from '@/types/assets';\nimport { Pagination, PendingTx, SimulationResult } from '@/types/msafe';\nimport { CoinHelper } from '@/utils';\nimport { HexToUint8Array } from '@/utils/buffer';\nimport { BatchObjectOptions, getAllOwnedObjects } from '@/utils/iter/object';\n\nexport class MSafeAccount {\n public multiSig: MultiSigAccount;\n\n private coinHelper: CoinHelper;\n\n constructor(\n public readonly globals: MSafeGlobals,\n public readonly info: IMSafeConfig,\n ) {\n this.multiSig = new MultiSigAccount({\n threshold: info.threshold,\n ownersWithWeight: info.owners,\n creationNonce: info.creationNonce,\n });\n this.coinHelper = new CoinHelper(this.suiClient);\n }\n\n static async New(globals: MSafeGlobals, address: string) {\n const info = await globals.backend.getMSafeAccountInfo(address);\n const ms = new MSafeAccount(globals, info);\n if (ms.address !== address) {\n throw new Error('Invalid msafe config with address');\n }\n }\n\n async ownedCoins(): Promise<OwnedCoin[]> {\n const balances = await this.suiClient.getAllBalances({ owner: this.address });\n return Promise.all(\n balances.map(async (balance): Promise<OwnedCoin> => {\n const meta = await this.coinHelper.getCoinMeta(balance.coinType);\n const unlockedBalance = balance.lockedBalance.number\n ? BigInt(balance.totalBalance) - BigInt(balance.lockedBalance.number)\n : BigInt(balance.totalBalance);\n\n return {\n type: normalizeStructTag(balance.coinType),\n balance: BigInt(unlockedBalance),\n metadata: meta,\n };\n }),\n );\n }\n\n async ownedObjects(options?: BatchObjectOptions): Promise<SuiObjectData[]> {\n const filterCoinObjectOptions = {\n filter: (objRes: SuiObjectResponse) => !objRes?.data?.type?.startsWith('0x2::coin::Coin'),\n ...options,\n };\n return getAllOwnedObjects(this.suiClient, this.address, filterCoinObjectOptions);\n }\n\n // TODO: Calculate the votes\n async pendingTransaction(): Promise<PendingTx | undefined> {\n const res = await this.backend.getPendingTransactions({ msafeAddress: this.address });\n if (!res.pending) {\n return undefined;\n }\n\n const pendingTx = res.pending;\n const rejectPending = res.reject;\n\n return {\n txType: TransactionType.Assets,\n txSubType:\n 'coinType' in pendingTx.intention\n ? TransactionSubTypes.assets.coin.send\n : TransactionSubTypes.assets.object.send,\n createdAt: pendingTx.createdAt as Date,\n creator: pendingTx.creator,\n digest: pendingTx.digest,\n intention: pendingTx.intention,\n sequenceNumber: pendingTx.sequenceNumber,\n payload: pendingTx.payload,\n votes: pendingTx.votes,\n approvalWeight: this.calculateWeightFromVotes(pendingTx.votes),\n msafeAddress: pendingTx.msafeAddress,\n rejectDigest: rejectPending?.digest ?? '',\n rejectPayload: rejectPending?.payload ?? '',\n rejectVotes: rejectPending?.votes ?? [],\n rejectWeight: this.calculateWeightFromVotes(rejectPending?.votes ?? []),\n };\n }\n\n // TODO: Calculate the votes.\n async historyTransaction(pagination?: Pagination) {\n return this.backend.getHistoryTransactions({\n msafeAddress: this.address,\n ...pagination,\n });\n }\n\n async futureIntentions(pagination?: Pagination) {\n return this.backend.getFutureIntentions({ msafeAddress: this.address, ...pagination });\n }\n\n async currentSequenceNumber() {\n return this.backend.getCurrentSequenceNumber(this.address);\n }\n\n async nextSequenceNumber() {\n return this.backend.getNextSequenceNumber(this.address);\n }\n\n async proposeIntention(input: Omit<IProposeIntentionRequest, 'signature' | 'msafeAddress'>) {\n const message = SigningMessageHelper.proposeIntentionMessage({\n msafeAddress: this.address,\n intention: input.intention,\n sn: input.sequenceNumber,\n });\n const signature = await this.wallet.signPersonalMessage({\n messageStr: message,\n });\n\n await this.backend.proposeIntention({\n ...input,\n msafeAddress: this.address,\n signature: signature.signature,\n });\n }\n\n async proposeCoinTransferIntention(intention: CoinTransferIntention) {\n const sn = await this.nextSequenceNumber();\n return this.proposeIntention({\n application: TransactionDefaultApplication,\n txType: TransactionType.Assets,\n txSubType: TransactionSubTypes.assets.coin.send,\n sequenceNumber: sn,\n intention,\n });\n }\n\n async proposeObjectTransferIntention(intention: ObjectTransferIntention) {\n await buildObjectTransferTxb(this.suiClient, intention, this.address);\n const sn = await this.nextSequenceNumber();\n return this.proposeIntention({\n application: TransactionDefaultApplication,\n txType: TransactionType.Assets,\n txSubType: TransactionSubTypes.assets.object.send,\n sequenceNumber: sn,\n intention,\n });\n }\n\n async voteForTransaction(digest: string, payload: string) {\n const payloadBytes = HexToUint8Array(payload);\n const signature = await this.wallet.signTransactionBlock({ transactionBlock: payloadBytes });\n return this.backend.voteForTransaction({\n msafeAddress: this.address,\n digest,\n signature: signature.signature,\n });\n }\n\n // Shortcut for proposing a transaction to be a pending transaction, and add user vote to it.\n // Requires the multi-sig to be empty in pending transaction.\n async proposePendingTransaction(intention: TxIntention) {\n const txb = new TransactionBlock();\n const payload = await txb.build({ client: this.suiClient });\n const digest = await txb.getDigest({ client: this.suiClient });\n const signature = await this.wallet.signTransactionBlock({ transactionBlock: payload });\n return this.backend.proposePendingTransaction({\n msafeAddress: this.address,\n userAddress: await this.userAddress(),\n intention,\n digest,\n signature: signature.signature,\n });\n }\n\n async rejectCurrentTx() {\n const pendingTx = await this.pendingTransaction();\n if (!pendingTx || pendingTx.rejectDigest !== '') {\n throw new Error('Already rejected');\n }\n\n const payloadToReject = pendingTx.payload;\n const rejectTxb = buildRejectTxb(this.address, payloadToReject);\n const digest = await rejectTxb.getDigest({ client: this.suiClient });\n const payload = await rejectTxb.build({ client: this.suiClient });\n const signature = await this.wallet.signTransactionBlock({ transactionBlock: payload });\n return this.backend.rejectCurrentTx({\n msafeAddress: this.address,\n digest,\n signature: signature.signature,\n });\n }\n\n async buildNextIntentionAndAddToPending() {\n return this.backend.buildNextIntentionAndAddToPending({ msafeAddress: this.address });\n }\n\n async skipNextFailedIntention() {\n return this.backend.skipNextFailedIntention({ msafeAddress: this.address });\n }\n\n async simulateIntention(): Promise<SimulationResult> {\n // Todo, move to API\n const txb = new TransactionBlock(); // await buildIntentionTransaction(this.suiClient, intention, this.address);\n txb.setSender(this.address);\n if (!txb.blockData.gasConfig.price) {\n const refGas = await this.suiClient.getReferenceGasPrice();\n txb.setGasPrice(refGas);\n }\n const payload = await txb.build({ client: this.suiClient });\n const dryRunResult = await this.suiClient.dryRunTransactionBlock({ transactionBlock: payload });\n\n const success = dryRunResult.effects.status.status === 'success';\n const errorMsg = dryRunResult.effects.status.error;\n const gasPrice = BigInt(txb.blockData.gasConfig.price as string);\n const { gasUsed } = dryRunResult.effects;\n\n return {\n success,\n errorMsg,\n gasPrice,\n gasUsed,\n dryRunResult,\n };\n }\n\n async executePendingTx(pending: PendingTx, isRejectTx: boolean = false) {\n const votes = isRejectTx ? pending.rejectVotes : pending.votes;\n const payload = isRejectTx ? pending.rejectPayload : pending.payload;\n\n if (this.calculateWeightFromVotes(votes) < this.info.threshold) {\n throw new Error('Not enough signature');\n }\n\n const sortedSigs: SerializedSignature[] = [];\n const gotSigs = new Map(votes.map((vote) => [vote.userAddress, vote.signature]));\n for (let i = 0; i < this.info.owners.length; i++) {\n const owner = this.info.owners[i];\n const signature = gotSigs.get(owner.address);\n if (signature) {\n sortedSigs.push(signature);\n }\n }\n const multiSignature = this.multiSig.combinePartialSignatures(sortedSigs);\n return this.suiClient.executeTransactionBlock({\n transactionBlock: HexToUint8Array(payload),\n signature: multiSignature,\n options: { showEffects: true },\n });\n }\n\n private calculateWeightFromVotes(votes: { userAddress: string }[]) {\n return this.calculateWeight(votes.map((vote) => vote.userAddress));\n }\n\n private calculateWeight(addressList: string[]) {\n let gotWeight = 0;\n\n for (let i = 0; i < addressList.length; i++) {\n const found = this.info.owners.find((owner) => isSameAddress(owner.address, addressList[i]));\n if (found) {\n gotWeight += found.weight;\n }\n }\n return gotWeight;\n }\n\n get address() {\n return this.multiSig.address;\n }\n\n private get backend() {\n return this.globals.backend;\n }\n\n private get wallet() {\n return this.globals.wallet;\n }\n\n private async userAddress() {\n return this.globals.wallet.address();\n }\n\n private get suiClient() {\n return this.globals.suiClient;\n }\n}\n","export function stringToBuffer(s: string) {\n return Buffer.from(s, 'utf-8');\n}\n\nexport function Uint8ArrayToHex(b: Uint8Array): string {\n return `0x${Array.prototype.map.call(b, (x) => `0${x.toString(16)}`.slice(-2)).join('')}`;\n}\n\nexport function HexToUint8Array(hex: string): Uint8Array {\n return Uint8Array.from(Buffer.from(hex.startsWith('0x') ? hex.slice(2) : hex, 'hex'));\n}\n","import { SerializedSignature } from '@mysten/sui.js/cryptography';\nimport { verifyPersonalMessage, verifyTransactionBlock } from '@mysten/sui.js/verify';\n\nimport { stringToBuffer } from '@/utils/buffer';\nimport { Formatter } from '@/utils/format';\n\nexport class SignatureVerifier {\n static async getPublicKeyFromSignature(input: {\n message: Uint8Array;\n messageType: 'TransactionBlock' | 'Personal';\n signature: SerializedSignature;\n }) {\n if (input.messageType === 'TransactionBlock') {\n return verifyTransactionBlock(input.message, input.signature);\n }\n return verifyPersonalMessage(input.message, input.signature);\n }\n\n static async getPublicKeyFromPersonalSignature(input: { messageStr: string; signature: SerializedSignature }) {\n const message = stringToBuffer(input.messageStr);\n return this.getPublicKeyFromSignature({\n message,\n messageType: 'Personal',\n signature: input.signature,\n });\n }\n\n static async verifySignature(input: {\n message: Uint8Array;\n messageType: 'TransactionBlock' | 'Personal';\n signature: SerializedSignature;\n targetAddress: string;\n }) {\n const publicKey = await SignatureVerifier.getPublicKeyFromSignature(input);\n return Formatter.isSuiAddressEqual(publicKey.toSuiAddress(), input.targetAddress);\n }\n\n static async verifyPersonalSignature(input: {\n messageStr: string;\n signature: SerializedSignature;\n targetAddress: string;\n }) {\n const message = stringToBuffer(input.messageStr);\n return this.verifySignature({\n message,\n messageType: 'Personal',\n signature: input.signature,\n targetAddress: input.targetAddress,\n });\n }\n\n static async verifyTransactionSignature(input: {\n payload: Uint8Array;\n signature: SerializedSignature;\n targetAddress: string;\n }): Promise<boolean> {\n return this.verifySignature({\n messageType: 'TransactionBlock',\n message: input.payload,\n signature: input.signature,\n targetAddress: input.targetAddress,\n });\n }\n}\n","import { normalizeSuiAddress, normalizeStructTag } from '@mysten/sui.js/utils';\n\nimport { Coin } from '@/utils/coin';\n\nexport class Formatter {\n static normalizeSuiAddress(addr: string) {\n return normalizeSuiAddress(addr);\n }\n\n static normalizeStructTag(struct: string) {\n return normalizeStructTag(struct);\n }\n\n static isSuiAddressEqual(addr1: string, addr2: string) {\n return normalizeSuiAddress(addr1) === normalizeSuiAddress(addr2);\n }\n\n static isSuiStructEqual(struct1: string, struct2: string) {\n return normalizeStructTag(struct1) === normalizeStructTag(struct2);\n }\n\n static isCoinObjectType(struct: string) {\n return Coin.isCoin(struct);\n }\n}\n","import { CoinMetadata, SuiClient, SuiObjectData } from '@mysten/sui.js/client';\nimport { normalizeStructTag } from '@mysten/sui.js/utils';\n\n// CoinHelper is the coin helper to query for coin metadata.\nexport class CoinHelper {\n private _client: SuiClient;\n\n private _coinMetaReg: Map<string, CoinMetadata>;\n\n constructor(client: SuiClient) {\n this._client = client;\n this._coinMetaReg = new Map();\n }\n\n async getCoinMeta(coinType: string): Promise<CoinMetadata | undefined> {\n const normalized = normalizeStructTag(coinType);\n if (this._coinMetaReg.has(normalized)) {\n return this._coinMetaReg.get(normalized);\n }\n const meta = await this.queryCoinMeta(normalized);\n if (meta) {\n this._coinMetaReg.set(normalized, meta);\n }\n return meta;\n }\n\n private async queryCoinMeta(coinType: string): Promise<CoinMetadata | undefined> {\n const res = await this._client.getCoinMetadata({ coinType });\n return res || undefined;\n }\n}\n\n// Copied from sui/sdk/typescript/src/framework/framework.ts\n\nexport const COIN_TYPE_ARG_REGEX =\n /^0x0000000000000000000000000000000000000000000000000000000000000002::coin::Coin<(.+)>$/;\n\nexport class Coin {\n static isCoin(type: string | undefined | null): boolean {\n if (!type) {\n return false;\n }\n return normalizeStructTag(type).match(COIN_TYPE_ARG_REGEX) != null;\n }\n\n static getCoinType(type: string) {\n const [, res] = normalizeStructTag(type).match(COIN_TYPE_ARG_REGEX) ?? [];\n return res || null;\n }\n\n static getBalance(data: SuiObjectData): bigint | undefined {\n if (!Coin.isCoin(data.type)) {\n return undefined;\n }\n if (data.content?.dataType !== 'moveObject') {\n return undefined;\n }\n const { balance } = data.content?.fields as any;\n if (balance === undefined) {\n return undefined;\n }\n return BigInt(balance);\n }\n}\n","import { PublicKeySerde } from '@msafe/sui3-utils';\nimport { SuiClient, PaginatedTransactionResponse, PaginatedCoins, CoinStruct } from '@mysten/sui.js/client';\nimport { parseSerializedSignature, PublicKey, SerializedSignature } from '@mysten/sui.js/cryptography';\nimport { MultiSigPublicKey } from '@mysten/sui.js/multisig';\n\nimport { Formatter } from '@/utils/format';\n\nexport const SUI_COIN = '0x2::sui::SUI';\n\nexport async function getPublicKeyFromChain(suiClient: SuiClient, address: string): Promise<PublicKey | undefined> {\n let txs: PaginatedTransactionResponse;\n try {\n txs = await suiClient.queryTransactionBlocks({\n // Disable naming rule since the variable is defined by Mysten\n filter: { FromAddress: address },\n options: { showInput: true },\n limit: 2,\n });\n } catch (e) {\n // Currently when there is no history transaction, will report an error:\n // Error: byte deserialization failed, cause by: Odd number of digits\n // TODO: remove the catch logic when sui part is fixed;\n return undefined;\n }\n\n if (txs.data.length === 0 || !txs.data[0].transaction?.txSignatures) {\n return undefined;\n }\n const tx = txs.data[0];\n const signatures = tx.transaction?.txSignatures as string[];\n\n for (let i = 0; i !== signatures.length; i++) {\n const serializedSig = signatures[i];\n const pk = getAddressFromSignatures(serializedSig, address);\n if (!pk) {\n continue;\n }\n return pk;\n }\n return undefined;\n}\n\nfunction getAddressFromSignatures(serializedSig: SerializedSignature, targetAddress: string) {\n const decoded = parseSerializedSignature(serializedSig);\n switch (decoded.signatureScheme) {\n case 'MultiSig': {\n const multiSigAddress = new MultiSigPublicKey(decoded.multisig.multisig_pk).toSuiAddress();\n if (Formatter.isSuiAddressEqual(multiSigAddress, targetAddress)) {\n throw new Error('multi-sig wallet cannot be owner');\n }\n return undefined;\n }\n case 'ZkLogin': {\n if (Formatter.isSuiAddressEqual(decoded.zkLogin.address, targetAddress)) {\n throw new Error('ZkLogin wallet cannot be owner');\n }\n return undefined;\n }\n\n case 'ED25519':\n case 'Secp256k1':\n case 'Secp256r1': {\n const pk = PublicKeySerde.de({ publicKeyEncoded: decoded.publicKey, schema: decoded.signatureScheme });\n if (Formatter.isSuiAddressEqual(pk.toSuiAddress(), targetAddress)) {\n return pk;\n }\n return undefined;\n }\n\n default:\n throw new Error('Unknown schema');\n }\n}\n\nexport async function getAllCoins(input: { suiClient: SuiClient; owner: string; coinType: string | undefined }) {\n let hasNext = true;\n let cursor: string | undefined | null;\n const res: CoinStruct[] = [];\n while (hasNext) {\n const currentPage: PaginatedCoins = await input.suiClient.getCoins({\n owner: input.owner,\n coinType: input.coinType,\n cursor,\n });\n res.push(...currentPage.data);\n hasNext = currentPage.hasNextPage;\n cursor = currentPage.nextCursor;\n }\n return res;\n}\n","import { PagedData, Requester } from './requester';\n\nexport const REQUEST_PAGE_SIZE = 25;\n\nexport interface SuiIterator<T> {\n next: () => Promise<T | undefined>;\n hasNext: () => Promise<boolean>;\n}\n\nexport async function getAllFromIterator<T>(it: SuiIterator<T>): Promise<(T | undefined) | (T | undefined)[]> {\n const res: (T | undefined)[] = [];\n while (await it.hasNext()) {\n const val = await it.next();\n res.push(val);\n }\n if (res && Array.isArray(res[0])) {\n return res.flat(1) as T;\n }\n return res;\n}\n\nexport class PagedIterator<T> implements SuiIterator<(T | undefined)[]> {\n private curPage: PagedData<T> | undefined;\n\n private init: boolean;\n\n constructor(public readonly requester: Requester<T>) {\n this.curPage = undefined;\n this.init = true;\n }\n\n async hasNext(): Promise<boolean> {\n if (this.init) {\n if (!this.curPage) {\n this.curPage = await this.requester.doNextRequest();\n }\n return !!this.curPage.data?.length || this.curPage.hasNext;\n }\n if (!this.curPage) {\n throw new Error('invalid implementation of iterator');\n }\n return this.curPage.hasNext;\n }\n\n async next(): Promise<(T | undefined)[]> {\n if (this.init) {\n this.init = false;\n if (!this.curPage) {\n this.curPage = await this.requester.doNextRequest();\n }\n return this.curPage.data;\n }\n this.curPage = await this.requester.doNextRequest();\n return this.curPage.data;\n }\n}\n\nexport class EntryIterator<T> implements SuiIterator<T> {\n cursor: number;\n\n pager: PagedIterator<T>;\n\n curData: (T | undefined)[];\n\n constructor(public readonly requester: Requester<T>) {\n this.pager = new PagedIterator<T>(requester);\n this.curData = [];\n this.cursor = 0;\n }\n\n async hasNext(): Promise<boolean> {\n if (this.cursor < this.curData.length - 1) {\n return true;\n }\n return this.pager.hasNext();\n }\n\n async next(): Promise<T | undefined> {\n this.cursor += 1;\n while (this.cursor >= this.curData.length) {\n if (!(await this.pager.hasNext())) {\n throw new Error('not more data'); // Shall not happen for legit data source.\n } else {\n this.curData = await this.pager.next();\n this.cursor = 0;\n }\n }\n return this.curData[this.cursor];\n }\n}\n","import { SuiObjectResponse, SuiObjectDataOptions, SuiObjectData, SuiClient } from '@mysten/sui.js/client';\n\nimport { EntryIterator, getAllFromIterator, REQUEST_PAGE_SIZE, SuiIterator } from './iterator';\nimport { PagedData, Requester } from './requester';\n\n// TODO: setup testnet faucet and test this file\n\nexport type ObjectFilter = (objRes: SuiObjectResponse) => boolean;\n\n// OidIter is the iterator to give the list of object ids\nexport type OidIter = SuiIterator<string>;\n\nexport interface BatchObjectOptions {\n filter?: ObjectFilter;\n pageSize?: number;\n objectOptions?: SuiObjectDataOptions;\n}\n\n// getObjectsById get the list of objects by id.\n// Compared with the multiGetObject method defined by SUI, this method will do the pagination\n// for get object requests.\nexport async function getObjectsById(\n provider: SuiClient,\n ids: string[],\n options?: BatchObjectOptions,\n): Promise<(SuiObjectData | undefined)[]> {\n const oidIter = new ListOidIterator(ids);\n const iter = new ObjectBatchIterator(provider, oidIter, options);\n return (await getAllFromIterator(iter)) as (SuiObjectData | undefined)[];\n}\n\n// ListOidIterator is the iterator that iterate through a list of ids.\n// This iterator shall be used when the number requested objects is big\n// which is inappropriate to fit the requested objects into a single\n// request.\nexport class ListOidIterator implements OidIter {\n cursor: number;\n\n constructor(public readonly ids: string[]) {\n this.cursor = -1;\n }\n\n async hasNext(): Promise<boolean> {\n return this.cursor < this.ids.length - 1;\n }\n\n async next(): Promise<string> {\n this.cursor += 1;\n if (this.cursor >= this.ids.length) {\n throw new Error('invalid iterator implementation'); // Shall be unreachable\n }\n return this.ids[this.cursor];\n }\n}\n\nexport class ObjectBatchIterator extends EntryIterator<SuiObjectData> {\n constructor(\n public readonly provider: SuiClient,\n public readonly idIter: OidIter,\n public readonly options?: BatchObjectOptions,\n ) {\n super(new ObjectBatchRequester(provider, idIter, options));\n }\n}\n\n// TODO: Test with customize objects\nexport class ObjectBatchRequester implements Requester<SuiObjectData> {\n filter: ObjectFilter | undefined;\n\n pageSize: number;\n\n objectOptions: SuiObjectDataOptions;\n\n constructor(\n public readonly provider: SuiClient,\n public readonly stringIter: OidIter,\n public options?: BatchObjectOptions,\n ) {\n this.filter = options?.filter;\n this.pageSize = options?.pageSize || REQUEST_PAGE_SIZE;\n this.objectOptions = options?.objectOptions || {\n showType: true,\n showContent: true,\n };\n }\n\n async doNextRequest(): Promise<PagedData<SuiObjectData>> {\n const requestPage: string[] = [];\n while (requestPage.length < this.pageSize) {\n const hasNext = await this.stringIter.hasNext();\n if (!hasNext) {\n break;\n }\n const objId = await this.stringIter.next();\n if (objId) {\n requestPage.push(objId);\n }\n }\n const res: SuiObjectResponse[] = await this.provider.multiGetObjects({\n ids: requestPage,\n options: this.objectOptions,\n });\n let filtered: SuiObjectResponse[];\n if (this.filter) {\n const { filter } = this;\n filtered = res.filter((r: SuiObjectResponse) => filter?.(r));\n } else {\n filtered = res;\n }\n return {\n data: filtered.map((objRes) => objRes.data).filter((data) => data) as SuiObjectData[],\n hasNext: await this.stringIter.hasNext(),\n };\n }\n}\n\nexport async function getAllOwnedObjects(\n provider: SuiClient,\n owner: string,\n options?: BatchObjectOptions,\n): Promise<SuiObjectData[]> {\n const iter = new OwnedObjectIterator(provider, owner, options);\n return (await getAllFromIterator(iter)) as SuiObjectData[];\n}\n\nexport class OwnedObjectIterator extends EntryIterator<SuiObjectData> implements SuiIterator<SuiObjectData> {\n constructor(\n public readonly provider: SuiClient,\n public readonly owner: string,\n public readonly options?: BatchObjectOptions,\n ) {\n super(new OwnedObjectRequester(provider, owner, options));\n }\n}\n\nexport class OwnedObjectRequester implements Requester<SuiObjectData> {\n nextCursor: string | null;\n\n public filter: ObjectFilter | undefined;\n\n public pageSize: number;\n\n public objectOptions: SuiObjectDataOptions;\n\n constructor(\n public readonly provider: SuiClient,\n public readonly owner: string,\n public readonly options?: BatchObjectOptions,\n ) {\n this.nextCursor = null;\n this.filter = options?.filter;\n this.pageSize = options?.pageSize || REQUEST_PAGE_SIZE;\n this.objectOptions = options?.objectOptions || {\n showType: true,\n showContent: true,\n };\n }\n\n async doNextRequest(): Promise<PagedData<SuiObjectData>> {\n const res = await this.provider.getOwnedObjects({\n owner: this.owner,\n options: this.objectOptions,\n cursor: this.nextCursor,\n limit: this.pageSize,\n });\n this.nextCursor = res.nextCursor as string;\n let filtered: SuiObjectResponse[];\n if (this.filter) {\n const { filter } = this;\n filtered = res.data.filter((obj: SuiObjectResponse) => filter?.(obj));\n } else {\n filtered = res.data;\n }\n return {\n data: filtered.map((r: SuiObjectResponse) => r.data).filter((data) => data) as SuiObjectData[],\n hasNext: res.hasNextPage,\n };\n }\n}\n","import { PublicKey } from '@mysten/sui.js/src/cryptography';\n\nimport { MSafeGlobals } from '@/globals/MSafeGlobals';\nimport { getPublicKeyFromChain } from '@/utils/sui';\n\n/**\n * PublicKeyHelper is the helper to query for public keys from\n * backend and blockchain.\n */\nexport class PublicKeyHelper {\n private knownPublicKeys: Map<string, PublicKey>;\n\n constructor(public readonly globals: MSafeGlobals) {\n this.knownPublicKeys = new Map<string, PublicKey>();\n }\n\n async getPublicKey(address: string) {\n const cached = this.knownPublicKeys.get(address);\n if (cached) {\n return cached;\n }\n const pk = await this._getPublicKey(address);\n if (pk) {\n this.knownPublicKeys.set(address, pk);\n }\n return pk;\n }\n\n async getPublicKeyBatch(addresses: string[]): Promise<(PublicKey | undefined)[]> {\n const results: (PublicKey | undefined)[] = new Array(addresses.length).fill(undefined);\n\n // Query local cache first\n for (let i = 0; i < addresses.length; i++) {\n const address = addresses[i];\n results[i] = this.knownPublicKeys.get(address);\n }\n\n // Query backend in batch\n const emptyIndexes = results\n .map((elem, index) => (elem === undefined ? index : -1))\n .filter((index) => index !== -1);\n if (emptyIndexes.length === 0) {\n return results;\n }\n const backendResult = await this.globals.backend.getPublicKeyBatch(emptyIndexes.map((index) => addresses[index]));\n for (let i = 0; i < emptyIndexes.length; i++) {\n const index = emptyIndexes[i];\n results[index] = backendResult[i];\n }\n\n // Query the public key from blockchain\n for (let i = 0; i < results.length; i++) {\n if (results[i] === undefined) {\n results[i] = await this.getPublicKeyFromChain(addresses[i]);\n }\n }\n\n // Finally, write the public keys to the local cache\n for (let i = 0; i < addresses.length; i++) {\n if (results[i]) {\n this.knownPublicKeys.set(addresses[i], results[i] as PublicKey);\n }\n }\n return results;\n }\n\n private async _getPublicKey(address: string) {\n const pkBackend = await this.getPublicKeyFromBackend(address);\n if (pkBackend) {\n return pkBackend;\n }\n const pkChain = await this.getPublicKeyFromChain(address);\n if (pkChain) {\n return pkChain;\n }\n return undefined;\n }\n\n private async getPublicKeyFromBackend(address: string): Promise<PublicKey | undefined> {\n try {\n const pk = await this.globals.backend.getPublicKey(address);\n return pk;\n } catch (_) {\n return undefined;\n }\n }\n\n private async getPublicKeyFromChain(address: string): Promise<PublicKey | undefined> {\n return getPublicKeyFromChain(this.globals.suiClient, address);\n }\n}\n","import { SuiClient } from '@mysten/sui.js/client';\n\nimport { BackendImpl } from '@/backend/BackendImpl';\nimport { IBackend } from '@/backend/interface';\nimport { getMSafeConfig, MSafeConfig, MSafeConfigOptions, MSafeEnv } from '@/globals/const';\nimport { IWallet } from '@/types/wallet';\n\nexport class MSafeGlobals {\n public readonly backend: IBackend;\n\n public readonly suiClient: SuiClient;\n\n public readonly config: MSafeConfig;\n\n _wallet: IWallet | undefined;\n\n constructor(input: { backend: IBackend; suiClient: SuiClient; config: MSafeConfig }) {\n this.backend = input.backend;\n this.suiClient = input.suiClient;\n this.config = input.config;\n }\n\n static async New(env: MSafeEnv, options?: MSafeConfigOptions) {\n const config = getMSafeConfig(env, options);\n const suiClient = new SuiClient(config.suiClient);\n const backend = new BackendImpl(config.backend.url);\n return new MSafeGlobals({\n backend,\n suiClient,\n config,\n });\n }\n\n connectWallet(wallet: IWallet) {\n this._wallet = wallet;\n }\n\n get wallet() {\n if (!this._wallet) {\n throw new Error('wallet not connected');\n }\n return this._wallet;\n }\n\n set wallet(val: IWallet) {\n this._wallet = val;\n }\n}\n","import {\n GetHistoryTransactionsResponse,\n GetPendingTransactionResponse,\n GetTransactionIntentionsResponse,\n IAuthLoginReq,\n IAuthLoginResp,\n IBuildTransactionRequest,\n ICreateMSafeReq,\n IGetAddressBookResult,\n IGetHistoryTransactionsRequest,\n IGetIntentionsRequest,\n IGetMSafeQuery,\n IGetMSafesQuery,\n IGetPendingTransactionRequest,\n IGetPublicKeyBatchQuery,\n IGetPublicKeyBatchResp,\n IMSafeConfig,\n IMSafeInfoResp,\n IPageOptions,\n IPagedResult,\n IProposeIntentionRequest,\n ISkipIntentionRequest,\n IUpdateMSafeStatusReq,\n IUserInfoResp,\n IVoteTransactionRequest,\n JWTToken,\n PublicKeySerde,\n TxIntention,\n UpdateAddressBookEntry,\n UserMSafeStatus,\n} from '@msafe/sui3-utils';\nimport { SerializedSignature } from '@mysten/sui.js/cryptography';\nimport { PublicKey } from '@mysten/sui.js/src/cryptography';\nimport axios from 'axios';\n\nimport { IBackend } from '@/backend/interface';\n\nexport class BackendImpl implements IBackend {\n private _token: JWTToken;\n\n constructor(private readonly apiURL: string) {}\n\n async authSign(input: IAuthLoginReq): Promise<JWTToken> {\n const res = await axios.post<IAuthLoginResp>(`${this.apiURL}/auth/login`, input);\n // TODO unify response struct\n if (res.status !== 200 && res.status !== 201) {\n throw new Error(`invalid authSign return: ${res}`);\n }\n this._token = res.data.accessToken;\n return this._token;\n }\n\n async verifyToken(jwt: JWTToken): Promise<boolean> {\n try {\n const res = await axios.get(`${this.apiURL}/auth`, { headers: this.headers(jwt) });\n return res.status === 200;\n } catch (_) {\n return false;\n }\n }\n\n setJWTToken(token: JWTToken) {\n this._token = token;\n }\n\n async getPublicKey(address: string): Promise<PublicKey | undefined> {\n return (await this.getPublicKeyBatch([address]))[0];\n }\n\n async getPublicKeyBatch(addresses: string[]): Promise<(PublicKey | undefined)[]> {\n const query: IGetPublicKeyBatchQuery = {\n userAddressList: addresses,\n };\n const res = await axios.get<IGetPublicKeyBatchResp>(`${this.apiURL}/user/public-keys`, {\n params: query,\n headers: this.headers(),\n });\n\n // TODO unify response struct\n if (res.status !== 200 && res.status !== 201) {\n throw new Error(`invalid getPublicKeyBatch return: ${res}`);\n }\n return res.data?.map((publicKeyWithSchema) =>\n publicKeyWithSchema ? PublicKeySerde.de(publicKeyWithSchema) : undefined,\n );\n }\n\n async getMSafeAccountInfo(msafeAddress: string): Promise<IMSafeConfig> {\n const q: IGetMSafeQuery = {\n msafeAddress,\n };\n const res = await axios.get<IMSafeInfoResp>(`${this.apiURL}/msafe`, {\n params: q,\n headers: this.headers(),\n });\n // TODO unify response struct\n if (res.status !== 200 && res.status !== 201) {\n throw new Error(`invalid getPublicKeyBatch return: ${res}`);\n }\n return BackendImpl.toMSafeConfig(res.data);\n }\n\n async getUserInfo(): Promise<IUserInfoResp> {\n const userRes = await axios.get<IUserInfoResp>(`${this.apiURL}/user`, {\n headers: this.headers(),\n });\n // TODO unify response struct\n if (userRes.status !== 200 && userRes.status !== 201) {\n throw new Error(`invalid getPublicKeyBatch return: ${userRes}`);\n }\n return userRes.data;\n }\n\n async getOwnedMSafeByStatus(input: {\n status?: UserMSafeStatus;\n pagination?: IPageOptions;\n }): Promise<IPagedResult<IMSafeConfig>> {\n const q: IGetMSafesQuery = {\n status: input.status ?? UserMSafeStatus.active,\n ...(input.pagination\n ? {\n page: input.pagination.page.toString(),\n limit: input.pagination.limit.toString(),\n }\n : {}),\n };\n const res = await axios.get<IPagedResult<IMSafeInfoResp>>(`${this.apiURL}/msafe/owned`, {\n params: q,\n headers: this.headers(),\n });\n if (res.status !== 200 && res.status !== 201) {\n throw new Error(`invalid getOwnedMSafeByStatus return: ${res}`);\n }\n return {\n data: res.data.data.map(BackendImpl.toMSafeConfig),\n meta: res.data.meta,\n };\n }\n\n async updateMSafeStatus(input: { msafeAddress: string; status: UserMSafeStatus }): Promise<void> {\n const p: IUpdateMSafeStatusReq = input;\n const res = await axios.post(`${this.apiURL}/msafe/status`, p, { headers: this.headers() });\n if (res.status !== 200 && res.status !== 201) {\n throw new Error(`Invalid updateMSafeStatus return: ${res}`);\n }\n }\n\n async getPendingTransactions(input: IGetPendingTransactionRequest): Promise<GetPendingTransactionResponse> {\n const res = await axios.get<GetPendingTransactionResponse>(`${this.apiURL}/transaction/pending`, {\n params: input,\n headers: this.headers(),\n });\n if (res.status !== 200 && res.status !== 201) {\n throw new Error(`invalid getPublicKeyBatch return: ${res}`);\n }\n return res.data;\n }\n\n async getHistoryTransactions(input: IGetHistoryTransactionsRequest): Promise<GetHistoryTransactionsResponse> {\n const res = await axios.get<GetHistoryTransactionsResponse>(`${this.apiURL}/transaction/history`, {\n params: input,\n headers: this.headers(),\n });\n if (res.status !== 200 && res.status !== 201) {\n throw new Error(`invalid getCurrentSequenceNumber return: ${res}`);\n }\n return res.data;\n }\n\n async getFutureIntentions(input: IGetIntentionsRequest): Promise<GetTransactionIntentionsResponse> {\n const res = await axios.get<GetTransactionIntentionsResponse>(`${this.apiURL}/transaction/intention`, {\n params: input,\n headers: this.headers(),\n });\n if (res.status !== 200 && res.status !== 201) {\n throw new Error(`invalid getCurrentSequenceNumber return: ${res}`);\n }\n return res.data;\n }\n\n async getCurrentSequenceNumber(address: string): Promise<number> {\n const res = await axios.get<number>(`${this.apiURL}/transaction/sn/current`, {\n params: {\n msafeAddress: address,\n },\n headers: this.headers(),\n });\n if (res.status !== 200 && res.status !== 201) {\n throw new Error(`invalid getCurrentSequenceNumber return: ${res}`);\n }\n return res.data;\n }\n\n async getNextSequenceNumber(address: string): Promise<number> {\n const res = await axios.get<number>(`${this.apiURL}/transaction/sn/next`, {\n params: {\n msafeAddress: address,\n },\n headers: this.headers(),\n });\n if (res.status !== 200 && res.status !== 201) {\n throw new Error(`invalid getNextSequenceNumber return: ${res}`);\n }\n return res.data;\n }\n\n async createMSafeAccount(input: ICreateMSafeReq): Promise<void> {\n const res = await axios.post(`${this.apiURL}/msafe/create`, input, {\n headers: this.headers(),\n });\n if (res.status !== 200 && res.status !== 201) {\n throw new Error(`invalid createMSafeAccount return: ${res}`);\n }\n }\n\n async proposeIntention(input: IProposeIntentionRequest): Promise<void> {\n const res = await axios.post(`${this.apiURL}/transaction/intention`, input, { headers: this.headers() });\n if (res.status !== 200 && res.status !== 201) {\n throw new Error(`invalid proposeIntention return: ${res}`);\n }\n }\n\n // TODO later\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n async proposePendingTransaction(_input: {\n intention: TxIntention;\n userAddress: string;\n msafeAddress: string;\n digest: string;\n signature: SerializedSignature;\n }): Promise<void> {\n return undefined;\n }\n\n async rejectCurrentTx(input: IVoteTransactionRequest) {\n const res = await axios.post(`${this.apiURL}/transaction/pending/reject`, input, {\n headers: this.headers(),\n });\n if (res.status !== 200 && res.status !== 201) {\n throw new Error(`invalid voteForTransaction return: ${res}`);\n }\n }\n\n async voteForTransaction(input: IVoteTransactionRequest) {\n const res = await axios.post(`${this.apiURL}/transaction/pending/vote`, input, {\n headers: this.headers(),\n });\n if (res.status !== 200 && res.status !== 201) {\n throw new Error(`invalid voteForTransaction return: ${res}`);\n }\n }\n\n async buildNextIntentionAndAddToPending(input: IBuildTransactionRequest) {\n const res = await axios.post(`${this.apiURL}/transaction/pending/build`, input, { headers: this.headers() });\n if (res.status !== 200 && res.status !== 201) {\n throw new Error(`invalid buildNextIntentionAndAddToPending return: ${res}`);\n }\n }\n\n async skipNextFailedIntention(input: ISkipIntentionRequest) {\n const res = await axios.post(`${this.apiURL}/transaction/pending/skip`, input, { headers: this.headers() });\n if (res.status !== 200 && res.status !== 201) {\n throw new Error(`invalid skipNextFailedIntention return: ${res}`);\n }\n }\n\n async getAddressBookEntries(pagination?: IPageOptions): Promise<IGetAddressBookResult> {\n const res = await axios.get<IGetAddressBookResult>(`${this.apiURL}/address-book`, {\n headers: this.headers(),\n params: pagination,\n });\n if (res.status !== 200) {\n throw new Error(`Invalid address-book return: ${res}`);\n }\n return res.data;\n }\n\n async updateAddressBook(input: { updates: UpdateAddressBookEntry[]; signature: SerializedSignature }) {\n const res = await axios.post(`${this.apiURL}/address-book`, input, { headers: this.headers() });\n if (res.status !== 200 && res.status !== 201) {\n throw new Error(`invalid updateAddressBook return: ${res}`);\n }\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n async processExecutedTransaction(_digest: string) {\n return undefined;\n }\n\n private headers(token?: string) {\n return { Authorization: `Bearer ${token || this._token}` };\n }\n\n private static toMSafeConfig(resp: IMSafeInfoResp): IMSafeConfig {\n return {\n ...resp,\n owners: resp.owners.map((owner) => ({\n address: owner.address,\n weight: owner.weight,\n publicKey: PublicKeySerde.de({\n publicKeyEncoded: owner.publicKeyEncoded,\n schema: owner.schema,\n }),\n })),\n };\n }\n}\n","export enum MSafeEnv {\n local = 'local',\n unit = 'unit',\n dev = 'dev',\n prev = 'prev',\n prod = 'prod',\n}\n\nexport interface MSafeConfig {\n suiClient: {\n url: string;\n };\n backend: {\n url: string;\n };\n syncingURL: string;\n}\n\nexport interface MSafeConfigOptions {\n suiClient?: {\n url?: string;\n };\n backend?: {\n url?: string;\n };\n}\nexport const MSAFE_APPLICATION = 'msafe';\n\nexport const TESTNET_RPC_URL = 'https://sui-testnet.blockvision.org/v1/2Sgk89ivT64MnKdcGzjmyjY2ndD';\nexport const MAINNET_RPC_URL = 'https://sui-mainnet.blockvision.org/v1/2Sgk7NPvqkd7mESYkxF01yX15l7';\n\nexport const LOCAL_API_URL = 'http://127.0.0.1:3000';\nexport const LOCAL_SYNCING_URL = 'http://127.0.0.1:3001';\n\nexport const DEV_API_URL = 'http://13.56.226.148';\nexport const DEV_SYNCING_URL = 'http://52.53.228.20';\n\nexport const ENV_CONFIGS = new Map<MSafeEnv, MSafeConfig>([\n [\n MSafeEnv.unit,\n {\n suiClient: {\n url: TESTNET_RPC_URL,\n },\n backend: {\n url: LOCAL_API_URL,\n },\n syncingURL: LOCAL_SYNCING_URL,\n },\n ],\n [\n MSafeEnv.local,\n {\n suiClient: {\n url: TESTNET_RPC_URL,\n },\n backend: {\n url: LOCAL_API_URL,\n },\n syncingURL: LOCAL_SYNCING_URL,\n },\n ],\n [\n MSafeEnv.dev,\n {\n suiClient: {\n url: TESTNET_RPC_URL,\n },\n backend: {\n url: DEV_API_URL,\n },\n syncingURL: DEV_SYNCING_URL,\n },\n ],\n]);\n\nexport function getMSafeConfig(env: MSafeEnv, options?: MSafeConfigOptions) {\n const config = ENV_CONFIGS.get(env);\n if (!config) {\n throw new Error('Unknown environment');\n }\n if (options?.suiClient?.url) {\n config.suiClient.url = options.suiClient.url;\n }\n if (options?.backend?.url) {\n config.backend.url = options.backend.url;\n }\n return config;\n}\n"],"mappings":"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","names":["SigningMessageHelper","UserMSafeStatus","SigningMessageHelper","MultiSigAccount","SigningMessageHelper","normalizeStructTag","normalizeStructTag","normalizeStructTag","PublicKeySerde","PublicKeySerde","MultiSigAccount","normalizeStructTag","SigningMessageHelper","PublicKeySerde","MSafeEnv","SigningMessageHelper","UserMSafeStatus"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@msafe/sui3-sdk",
3
- "version": "0.0.21",
3
+ "version": "0.0.22",
4
4
  "description": "SDK for MSafe SUI V3",
5
5
  "type": "module",
6
6
  "module": "./dist/index.js",
@@ -11,6 +11,7 @@ import {
11
11
  TxIntention,
12
12
  buildObjectTransferTxb,
13
13
  buildRejectTxb,
14
+ isSameAddress,
14
15
  } from '@msafe/sui3-utils';
15
16
  import { SuiObjectData } from '@mysten/sui.js/client';
16
17
  import { SerializedSignature } from '@mysten/sui.js/cryptography';
@@ -76,6 +77,7 @@ export class MSafeAccount {
76
77
  return getAllOwnedObjects(this.suiClient, this.address, filterCoinObjectOptions);
77
78
  }
78
79
 
80
+ // TODO: Calculate the votes
79
81
  async pendingTransaction(): Promise<PendingTx | undefined> {
80
82
  const res = await this.backend.getPendingTransactions({ msafeAddress: this.address });
81
83
  if (!res.pending) {
@@ -98,13 +100,16 @@ export class MSafeAccount {
98
100
  sequenceNumber: pendingTx.sequenceNumber,
99
101
  payload: pendingTx.payload,
100
102
  votes: pendingTx.votes,
103
+ approvalWeight: this.calculateWeightFromVotes(pendingTx.votes),
101
104
  msafeAddress: pendingTx.msafeAddress,
102
105
  rejectDigest: rejectPending?.digest ?? '',
103
106
  rejectPayload: rejectPending?.payload ?? '',
104
107
  rejectVotes: rejectPending?.votes ?? [],
108
+ rejectWeight: this.calculateWeightFromVotes(rejectPending?.votes ?? []),
105
109
  };
106
110
  }
107
111
 
112
+ // TODO: Calculate the votes.
108
113
  async historyTransaction(pagination?: Pagination) {
109
114
  return this.backend.getHistoryTransactions({
110
115
  msafeAddress: this.address,
@@ -241,28 +246,24 @@ export class MSafeAccount {
241
246
  };
242
247
  }
243
248
 
244
- async executePendingTx(pending: PendingTx) {
245
- let gotSigs: Map<string, string>;
246
- let payload: string;
247
- if (pending.votes.length >= this.info.threshold) {
248
- gotSigs = new Map(pending.votes.map((vote) => [vote.userAddress, vote.signature]));
249
- payload = pending.payload;
250
- } else if (pending.rejectVotes && pending.rejectPayload && pending.rejectVotes?.length >= this.info.threshold) {
251
- gotSigs = new Map(pending.rejectVotes.map((vote) => [vote.userAddress, vote.signature]));
252
- payload = pending.rejectPayload;
253
- } else {
254
- throw new Error('Not enough signatures');
249
+ async executePendingTx(pending: PendingTx, isRejectTx: boolean = false) {
250
+ const votes = isRejectTx ? pending.rejectVotes : pending.votes;
251
+ const payload = isRejectTx ? pending.rejectPayload : pending.payload;
252
+
253
+ if (this.calculateWeightFromVotes(votes) < this.info.threshold) {
254
+ throw new Error('Not enough signature');
255
255
  }
256
256
 
257
- const sigs: SerializedSignature[] = [];
257
+ const sortedSigs: SerializedSignature[] = [];
258
+ const gotSigs = new Map(votes.map((vote) => [vote.userAddress, vote.signature]));
258
259
  for (let i = 0; i < this.info.owners.length; i++) {
259
260
  const owner = this.info.owners[i];
260
261
  const signature = gotSigs.get(owner.address);
261
262
  if (signature) {
262
- sigs.push(signature);
263
+ sortedSigs.push(signature);
263
264
  }
264
265
  }
265
- const multiSignature = this.multiSig.combinePartialSignatures(sigs);
266
+ const multiSignature = this.multiSig.combinePartialSignatures(sortedSigs);
266
267
  return this.suiClient.executeTransactionBlock({
267
268
  transactionBlock: HexToUint8Array(payload),
268
269
  signature: multiSignature,
@@ -270,6 +271,22 @@ export class MSafeAccount {
270
271
  });
271
272
  }
272
273
 
274
+ private calculateWeightFromVotes(votes: { userAddress: string }[]) {
275
+ return this.calculateWeight(votes.map((vote) => vote.userAddress));
276
+ }
277
+
278
+ private calculateWeight(addressList: string[]) {
279
+ let gotWeight = 0;
280
+
281
+ for (let i = 0; i < addressList.length; i++) {
282
+ const found = this.info.owners.find((owner) => isSameAddress(owner.address, addressList[i]));
283
+ if (found) {
284
+ gotWeight += found.weight;
285
+ }
286
+ }
287
+ return gotWeight;
288
+ }
289
+
273
290
  get address() {
274
291
  return this.multiSig.address;
275
292
  }
@@ -12,9 +12,11 @@ export interface PendingTx {
12
12
  creator: string;
13
13
  createdAt: Date;
14
14
  sequenceNumber: number;
15
+ approvalWeight: number;
15
16
  votes: PendingVote[];
16
17
  rejectDigest: string;
17
18
  rejectPayload: string;
19
+ rejectWeight: number;
18
20
  rejectVotes: PendingVote[];
19
21
  }
20
22