{"version":3,"file":"wallet.mjs","names":[],"sources":["../../src/wallet/wallet.ts"],"sourcesContent":["import {\n  LedgerConnector,\n} from \"@cosmjs/ledger-amino\";\nimport {\n  AccountWalletOption,\n  BroadcastTransactionMap,\n  CreateWalletOptions,\n  Signer,\n  Tx,\n  TxFee,\n  Wallet,\n} from \"@gnolang/tm2-js-client\";\n\nimport {\n  MsgRun,\n} from \"../proto/gno/vm.js\";\nimport {\n  MemPackage, MsgAddPackage, MsgCall, MsgSend,\n} from \"../proto/index.js\";\nimport {\n  GnoProvider,\n} from \"../provider/index.js\";\nimport {\n  MsgEndpoint,\n} from \"./endpoints.js\";\nimport {\n  Constructor, Realm, Return, UnionToIntersection,\n} from \"./helpers.js\";\nimport {\n  decodeTxMessages, defaultTxFee, fundsToCoins,\n} from \"./utility/index.js\";\n\n/**\n * Remaps factory method return types so that calling e.g.\n * `AugmentedWallet.fromMnemonic(...)` returns `GnoWallet & Ext`.\n */\ntype AugmentedWalletStatics<Ext> = {\n  createRandom(options?: AccountWalletOption): Promise<GnoWallet & Ext>\n  fromSigner(signer: Signer): Promise<GnoWallet & Ext>\n  fromMnemonic(\n    mnemonic: string,\n    options?: CreateWalletOptions\n  ): Promise<GnoWallet & Ext>\n  fromPrivateKey(\n    privateKey: Uint8Array,\n    options?: AccountWalletOption\n  ): Promise<GnoWallet & Ext>\n  fromLedger(\n    connector: LedgerConnector,\n    options?: CreateWalletOptions\n  ): GnoWallet & Ext\n};\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction deepAssign(target: any, source: any): void {\n  for (const key of Object.keys(source)) {\n    const srcVal = source[key];\n    const tgtVal = target[key];\n    if (\n      tgtVal\n      && srcVal\n      && typeof tgtVal === \"object\"\n      && typeof srcVal === \"object\"\n      && Object.getPrototypeOf(srcVal) === Object.prototype\n      && Object.getPrototypeOf(tgtVal) === Object.prototype\n    ) {\n      deepAssign(tgtVal, srcVal);\n    }\n    else {\n      target[key] = srcVal;\n    }\n  }\n}\n\n/**\n * GnoWallet is an extension of the TM2 wallet with\n * specific functionality for Gno chains\n */\nexport class GnoWallet extends Wallet {\n  declare protected provider: GnoProvider;\n  static realms: Realm[] = [];\n  constructor() {\n    super();\n    const classConstructor = this.constructor as typeof GnoWallet;\n    classConstructor.realms.forEach((realm) => {\n      const realmInstance = realm(this);\n      deepAssign(this, realmInstance.realm);\n    });\n  }\n\n  static addRealm<T extends Realm | Realm[]>(realms: T) {\n    const currentRealms = this.realms;\n\n    class AugmentedWallet extends this {\n      static realms = currentRealms.concat(realms);\n    }\n\n    if (Array.isArray(realms)) {\n      type Extension = UnionToIntersection<Return<T>[\"realm\"]>;\n      return AugmentedWallet as Constructor<GnoWallet & Extension>\n        & AugmentedWalletStatics<Extension>\n        & typeof GnoWallet;\n    }\n\n    type Extension = Return<T>[\"realm\"];\n    return AugmentedWallet as Constructor<GnoWallet & Extension>\n      & AugmentedWalletStatics<Extension>\n      & typeof GnoWallet;\n  }\n\n  /**\n   * Generates a private key-based wallet, using a random seed\n   * @param {AccountWalletOption} options the account options\n   */\n  static async createRandom(options?: AccountWalletOption): Promise<GnoWallet> {\n    const wallet = await Wallet.createRandom(options);\n\n    const gnoWallet = new this();\n    gnoWallet.signer = wallet.getSigner();\n\n    return gnoWallet;\n  }\n\n  /**\n   * Generates a custom signer-based wallet\n   * @param {Signer} signer the custom signer implementing the Signer interface\n   */\n  static async fromSigner(signer: Signer): Promise<GnoWallet> {\n    const wallet = await Wallet.fromSigner(signer);\n\n    const gnoWallet = new this();\n    gnoWallet.signer = wallet.getSigner();\n\n    return gnoWallet;\n  }\n\n  /**\n   * Generates a bip39 mnemonic-based wallet\n   * @param {string} mnemonic the bip39 mnemonic\n   * @param {CreateWalletOptions} options the wallet generation options\n   */\n  static async fromMnemonic(\n    mnemonic: string,\n    options?: CreateWalletOptions,\n  ): Promise<GnoWallet> {\n    const wallet = await Wallet.fromMnemonic(mnemonic, options);\n\n    const gnoWallet = new this();\n    gnoWallet.signer = wallet.getSigner();\n\n    return gnoWallet;\n  }\n\n  /**\n   * Generates a private key-based wallet\n   * @param {string} privateKey the private key\n   * @param {AccountWalletOption} options the account options\n   */\n  static async fromPrivateKey(\n    privateKey: Uint8Array,\n    options?: AccountWalletOption,\n  ): Promise<GnoWallet> {\n    const wallet = await Wallet.fromPrivateKey(privateKey, options);\n\n    const gnoWallet = new this();\n    gnoWallet.signer = wallet.getSigner();\n\n    return gnoWallet;\n  }\n\n  /**\n   * Creates a Ledger-based wallet\n   * @param {LedgerConnector} connector the Ledger device connector\n   * @param {CreateWalletOptions} options the wallet generation options\n   */\n  static fromLedger(\n    connector: LedgerConnector,\n    options?: CreateWalletOptions,\n  ): GnoWallet {\n    const wallet = Wallet.fromLedger(connector, options);\n\n    const gnoWallet = new this();\n    gnoWallet.signer = wallet.getSigner();\n\n    return gnoWallet;\n  }\n\n  /**\n   * Returns the connected provider, if any\n   * (Here to ensure correct GnoProvider inference)\n   */\n  getProvider = (): GnoProvider => {\n    return this.provider;\n  };\n\n  /**\n   * Initiates a native currency transfer transaction between accounts\n   * @param {string} to the bech32 address of the receiver\n   * @param {Map<string, number>} funds the denomination -> value map for funds\n   * @param {TransactionEndpoint} endpoint the transaction broadcast type (sync / commit)\n   * @param {TxFee} [fee] the custom transaction fee, if any\n   */\n  transferFunds = async <K extends keyof BroadcastTransactionMap>(\n    to: string,\n    funds: Map<string, number>,\n    endpoint: K,\n    fee?: TxFee,\n  ): Promise<BroadcastTransactionMap[K][\"result\"]> => {\n    // Convert the funds into the correct representation\n    const amount: string = fundsToCoins(funds);\n\n    // Fetch the wallet address\n    const sender: string = await this.getAddress();\n\n    // Construct the transaction fee\n    const txFee: TxFee = fee\n      ? fee\n      : {\n        gas_wanted: 60000n,\n        gas_fee: defaultTxFee,\n      };\n\n    // Prepare the Msg\n    const sendMsg: MsgSend = {\n      from_address: sender,\n      to_address: to,\n      amount: amount,\n    };\n\n    // Construct the transfer transaction\n    const tx: Tx = {\n      messages: [\n        {\n          type_url: MsgEndpoint.MSG_SEND,\n          value: MsgSend.encode(sendMsg).finish(),\n        },\n      ],\n      fee: txFee,\n      memo: \"\",\n      signatures: [], // No signature yet\n    };\n\n    // Sign the transaction\n    const signedTx: Tx = await this.signTransaction(tx, decodeTxMessages);\n\n    // Send the transaction\n    return this.sendTransaction(signedTx, endpoint);\n  };\n\n  /**\n   * Invokes the specified method on a GNO contract\n   * @param {string} path the gno package / realm path\n   * @param {string} method the method name\n   * @param {string[]} args the method arguments, if any\n   * @param {TransactionEndpoint} endpoint the transaction broadcast type (sync / commit)\n   * @param {Map<string, number>} [funds] the denomination -> value map for funds, if any\n   * @param {Map<string, number>} [maxDeposit] the denomination -> value map for max storage deposit, if any\n   * @param {TxFee} [fee] the custom transaction fee, if any\n   */\n  callMethod = async <K extends keyof BroadcastTransactionMap>(\n    path: string,\n    method: string,\n    args: string[] | null,\n    endpoint: K,\n    funds?: Map<string, number>,\n    maxDeposit?: Map<string, number>,\n    fee?: TxFee,\n  ): Promise<BroadcastTransactionMap[K][\"result\"]> => {\n    // Convert the funds into the correct representation\n    const amount: string = fundsToCoins(funds);\n    const maxDepositAmount: string = fundsToCoins(maxDeposit);\n\n    // Fetch the wallet address\n    const caller: string = await this.getAddress();\n\n    // Construct the transaction fee\n    const txFee: TxFee = fee\n      ? fee\n      : {\n        gas_wanted: 60000n,\n        gas_fee: defaultTxFee,\n      };\n\n    // Prepare the Msg\n    const callMsg: MsgCall = {\n      caller: caller,\n      send: amount,\n      max_deposit: maxDepositAmount,\n      pkg_path: path,\n      func: method,\n      args: args || [],\n    };\n\n    // Construct the transfer transaction\n    const tx: Tx = {\n      messages: [\n        {\n          type_url: MsgEndpoint.MSG_CALL,\n          value: MsgCall.encode(callMsg).finish(),\n        },\n      ],\n      fee: txFee,\n      memo: \"\",\n      signatures: [], // No signature yet\n    };\n\n    // Sign the transaction\n    const signedTx: Tx = await this.signTransaction(tx, decodeTxMessages);\n\n    // Send the transaction\n    return this.sendTransaction(signedTx, endpoint);\n  };\n\n  /**\n   * Deploys the specified package / realm\n   * @param {MemPackage} gnoPackage the package / realm to be deployed\n   * @param {TransactionEndpoint} endpoint the transaction broadcast type (sync / commit)\n   * @param {Map<string, number>} [funds] the denomination -> value map for funds, if any\n   * @param {Map<string, number>} [maxDeposit] the denomination -> value map for max storage deposit, if any\n   * @param {TxFee} [fee] the custom transaction fee, if any\n   */\n  deployPackage = async <K extends keyof BroadcastTransactionMap>(\n    gnoPackage: MemPackage,\n    endpoint: K,\n    funds?: Map<string, number>,\n    maxDeposit?: Map<string, number>,\n    fee?: TxFee,\n  ): Promise<BroadcastTransactionMap[K][\"result\"]> => {\n    // Convert the funds into the correct representation\n    const amount: string = fundsToCoins(funds);\n    const maxDepositAmount: string = fundsToCoins(maxDeposit);\n\n    // Fetch the wallet address\n    const caller: string = await this.getAddress();\n\n    // Construct the transaction fee\n    const txFee: TxFee = fee\n      ? fee\n      : {\n        gas_wanted: 60000n,\n        gas_fee: defaultTxFee,\n      };\n\n    // Prepare the Msg\n    const addPkgMsg: MsgAddPackage = {\n      creator: caller,\n      package: gnoPackage,\n      send: amount,\n      max_deposit: maxDepositAmount,\n    };\n\n    // Construct the transfer transaction\n    const tx: Tx = {\n      messages: [\n        {\n          type_url: MsgEndpoint.MSG_ADD_PKG,\n          value: MsgAddPackage.encode(addPkgMsg).finish(),\n        },\n      ],\n      fee: txFee,\n      memo: \"\",\n      signatures: [], // No signature yet\n    };\n\n    // Sign the transaction\n    const signedTx: Tx = await this.signTransaction(tx, decodeTxMessages);\n\n    // Send the transaction\n    return this.sendTransaction(signedTx, endpoint);\n  };\n\n  /**\n   * Executes arbitrary Gno code\n   * @param {MemPackage} gnoPackage the gno package being executed\n   * @param {TransactionEndpoint} endpoint the transaction broadcast type (sync / commit)\n   * @param {Map<string, number>} [funds] the denomination -> value map for funds, if any\n   * @param {Map<string, number>} [maxDeposit] the denomination -> value map for max storage deposit, if any\n   * @param {TxFee} [fee] the custom transaction fee, if any\n   */\n  executePackage = async <K extends keyof BroadcastTransactionMap>(\n    gnoPackage: MemPackage,\n    endpoint: K,\n    funds?: Map<string, number>,\n    maxDeposit?: Map<string, number>,\n    fee?: TxFee,\n  ): Promise<BroadcastTransactionMap[K][\"result\"]> => {\n    // Convert the funds into the correct representation\n    const amount: string = fundsToCoins(funds);\n    const maxDepositAmount: string = fundsToCoins(maxDeposit);\n\n    // Fetch the wallet address\n    const caller: string = await this.getAddress();\n\n    // Construct the transaction fee\n    const txFee: TxFee = fee\n      ? fee\n      : {\n        gas_wanted: 60000n,\n        gas_fee: defaultTxFee,\n      };\n\n    // Prepare the Msg\n    const runMsg: MsgRun = {\n      caller,\n      send: amount,\n      package: gnoPackage,\n      max_deposit: maxDepositAmount,\n    };\n\n    // Construct the transfer transaction\n    const tx: Tx = {\n      messages: [\n        {\n          type_url: MsgEndpoint.MSG_RUN,\n          value: MsgRun.encode(runMsg).finish(),\n        },\n      ],\n      fee: txFee,\n      memo: \"\",\n      signatures: [], // No signature yet\n    };\n\n    // Sign the transaction\n    const signedTx: Tx = await this.signTransaction(tx, decodeTxMessages);\n\n    // Send the transaction\n    return this.sendTransaction(signedTx, endpoint);\n  };\n}\n"],"mappings":";;;;;;;;;AAsDA,SAAS,WAAW,QAAa,QAAmB;AAClD,MAAK,MAAM,OAAO,OAAO,KAAK,OAAO,EAAE;EACrC,MAAM,SAAS,OAAO;EACtB,MAAM,SAAS,OAAO;AACtB,MACE,UACG,UACA,OAAO,WAAW,YAClB,OAAO,WAAW,YAClB,OAAO,eAAe,OAAO,KAAK,OAAO,aACzC,OAAO,eAAe,OAAO,KAAK,OAAO,UAE5C,YAAW,QAAQ,OAAO;MAG1B,QAAO,OAAO;;;;;;;AASpB,IAAa,YAAb,cAA+B,OAAO;CAGpC,cAAc;AACZ,SAAO;;;;;;;GA6GT;SAAiC;AAC/B,WAAO,KAAK;;GACZ;;;;;;;;;;GASF;GAAgB,OACd,IACA,OACA,UACA,QACkD;IAElD,MAAM,SAAiB,aAAa,MAAM;IAG1C,MAAM,SAAiB,MAAM,KAAK,YAAY;IAG9C,MAAM,QAAe,MACjB,MACA;KACA,YAAY;KACZ,SAAS;KACV;IAGH,MAAM,UAAmB;KACvB,cAAc;KACd,YAAY;KACJ;KACT;IAGD,MAAM,KAAS;KACb,UAAU,CACR;MACE,UAAU,YAAY;MACtB,OAAO,QAAQ,OAAO,QAAQ,CAAC,QAAQ;MACxC,CACF;KACD,KAAK;KACL,MAAM;KACN,YAAY,EAAE;KACf;IAGD,MAAM,WAAe,MAAM,KAAK,gBAAgB,IAAI,iBAAiB;AAGrE,WAAO,KAAK,gBAAgB,UAAU,SAAS;;GAC/C;;;;;;;;;;;;;GAYF;GAAa,OACX,MACA,QACA,MACA,UACA,OACA,YACA,QACkD;IAElD,MAAM,SAAiB,aAAa,MAAM;IAC1C,MAAM,mBAA2B,aAAa,WAAW;IAGzD,MAAM,SAAiB,MAAM,KAAK,YAAY;IAG9C,MAAM,QAAe,MACjB,MACA;KACA,YAAY;KACZ,SAAS;KACV;IAGH,MAAM,UAAmB;KACf;KACR,MAAM;KACN,aAAa;KACb,UAAU;KACV,MAAM;KACN,MAAM,QAAQ,EAAE;KACjB;IAGD,MAAM,KAAS;KACb,UAAU,CACR;MACE,UAAU,YAAY;MACtB,OAAO,QAAQ,OAAO,QAAQ,CAAC,QAAQ;MACxC,CACF;KACD,KAAK;KACL,MAAM;KACN,YAAY,EAAE;KACf;IAGD,MAAM,WAAe,MAAM,KAAK,gBAAgB,IAAI,iBAAiB;AAGrE,WAAO,KAAK,gBAAgB,UAAU,SAAS;;GAC/C;;;;;;;;;;;GAUF;GAAgB,OACd,YACA,UACA,OACA,YACA,QACkD;IAElD,MAAM,SAAiB,aAAa,MAAM;IAC1C,MAAM,mBAA2B,aAAa,WAAW;IAGzD,MAAM,SAAiB,MAAM,KAAK,YAAY;IAG9C,MAAM,QAAe,MACjB,MACA;KACA,YAAY;KACZ,SAAS;KACV;IAGH,MAAM,YAA2B;KAC/B,SAAS;KACT,SAAS;KACT,MAAM;KACN,aAAa;KACd;IAGD,MAAM,KAAS;KACb,UAAU,CACR;MACE,UAAU,YAAY;MACtB,OAAO,cAAc,OAAO,UAAU,CAAC,QAAQ;MAChD,CACF;KACD,KAAK;KACL,MAAM;KACN,YAAY,EAAE;KACf;IAGD,MAAM,WAAe,MAAM,KAAK,gBAAgB,IAAI,iBAAiB;AAGrE,WAAO,KAAK,gBAAgB,UAAU,SAAS;;GAC/C;;;;;;;;;;;GAUF;GAAiB,OACf,YACA,UACA,OACA,YACA,QACkD;IAElD,MAAM,SAAiB,aAAa,MAAM;IAC1C,MAAM,mBAA2B,aAAa,WAAW;IAGzD,MAAM,SAAiB,MAAM,KAAK,YAAY;IAG9C,MAAM,QAAe,MACjB,MACA;KACA,YAAY;KACZ,SAAS;KACV;IAGH,MAAM,SAAiB;KACrB;KACA,MAAM;KACN,SAAS;KACT,aAAa;KACd;IAGD,MAAM,KAAS;KACb,UAAU,CACR;MACE,UAAU,YAAY;MACtB,OAAO,OAAO,OAAO,OAAO,CAAC,QAAQ;MACtC,CACF;KACD,KAAK;KACL,MAAM;KACN,YAAY,EAAE;KACf;IAGD,MAAM,WAAe,MAAM,KAAK,gBAAgB,IAAI,iBAAiB;AAGrE,WAAO,KAAK,gBAAgB,UAAU,SAAS;;GAC/C;AAvVA,EADyB,KAAK,YACb,OAAO,SAAS,UAAU;GACzC,MAAM,gBAAgB,MAAM,KAAK;AACjC,cAAW,MAAM,cAAc,MAAM;IACrC;;CAGJ,OAAO,SAAoC,QAAW;EACpD,MAAM,gBAAgB,KAAK;EAE3B,MAAM,wBAAwB,KAAK;mCAC1B,UAAS,cAAc,OAAO,OAAO,CAAC;AAG/C,MAAI,MAAM,QAAQ,OAAO,CAEvB,QAAO;AAMT,SAAO;;;;;;CAST,aAAa,aAAa,SAAmD;EAC3E,MAAM,SAAS,MAAM,OAAO,aAAa,QAAQ;EAEjD,MAAM,YAAY,IAAI,MAAM;AAC5B,YAAU,SAAS,OAAO,WAAW;AAErC,SAAO;;;;;;CAOT,aAAa,WAAW,QAAoC;EAC1D,MAAM,SAAS,MAAM,OAAO,WAAW,OAAO;EAE9C,MAAM,YAAY,IAAI,MAAM;AAC5B,YAAU,SAAS,OAAO,WAAW;AAErC,SAAO;;;;;;;CAQT,aAAa,aACX,UACA,SACoB;EACpB,MAAM,SAAS,MAAM,OAAO,aAAa,UAAU,QAAQ;EAE3D,MAAM,YAAY,IAAI,MAAM;AAC5B,YAAU,SAAS,OAAO,WAAW;AAErC,SAAO;;;;;;;CAQT,aAAa,eACX,YACA,SACoB;EACpB,MAAM,SAAS,MAAM,OAAO,eAAe,YAAY,QAAQ;EAE/D,MAAM,YAAY,IAAI,MAAM;AAC5B,YAAU,SAAS,OAAO,WAAW;AAErC,SAAO;;;;;;;CAQT,OAAO,WACL,WACA,SACW;EACX,MAAM,SAAS,OAAO,WAAW,WAAW,QAAQ;EAEpD,MAAM,YAAY,IAAI,MAAM;AAC5B,YAAU,SAAS,OAAO,WAAW;AAErC,SAAO;;;2BAxGF,UAAkB,EAAE,CAAC"}