trustwallet / wallet-core

Cross-platform, cross-blockchain wallet library.
https://developer.trustwallet.com/wallet-core
Apache License 2.0
2.84k stars 1.6k forks source link

[Wasm] Codgen Typescript declaration #2164

Closed hewigovens closed 2 years ago

hewigovens commented 2 years ago
foogazy commented 2 years ago

Hello!

I was wondering if we can have the TS typedefs for the wallet-core? Is there anyway we can help to add that?

Thanks. Macie

hewigovens commented 2 years ago

@foogazy what are you building? It's possible to generate from https://github.com/trustwallet/wallet-core/tree/master/include/TrustWalletCore, currently exposed methods are generated from same headers

foogazy commented 2 years ago

@hewigovens Hi there! Thank you for getting back to me.

So we're building an exchange where we generate wallets for the users and they can do trading, etc.. on them within our system, however, the methods that we're using are in the WalletCore object which do not have typescript typings and we usually have to typecast them in order to get passed the typescript compiler:


import { WalletCore } from "@trustwallet/wallet-core";

...

  const { HDWallet, Mnemonic, CoinType } = WalletCore;

  const CC = CoinType as CointTypeType; // <- We have to manually type the properties 

  const wallet = HDWallet.create(256, "");

  console.log(wallet.mnemonic());
  console.log(wallet.getAddressForCoin(CC.ethereum));
  console.log(wallet.getAddressForCoin(CC.bitcoin));
  console.log(wallet.getAddressForCoin(CC.tron));
  console.log(wallet.getAddressForCoin(CC.binance));

  console.log(wallet. // <- No typesafety); 

...

So I was thinking for example in the wasm folder, the WalletCore is generating methods for JS and maybe we could use the package you mentioned above to generate typescript .d.ts files alongside them?

Also, thank you very much for this amazing package, it massively reduces the amount of code we've been writing previously and we're just waiting for the typesafety to do the full switch. If there's anything I can help with, please don't hesitate to let me know.

hewigovens commented 2 years ago

Can you try https://github.com/Microsoft/dts-gen to see if it works out of box? if not, we need to add templates to generate .d.ts for each class and enum: https://github.com/trustwallet/wallet-core/tree/master/codegen/lib/templates/cpp

foogazy commented 2 years ago

@hewigovens Hello! So I tried the dts-gen for the package running over @trustwallet/wallet-core but I had no luck, I believe the package couldn't find the runtime returns properly however it was able to return the TW protobufs somewhat ok because it already had .d.ts typings:

The output: ```ts /** Declaration file generated by dts-gen */ export = trustwallet__wallet_core; declare const trustwallet__wallet_core: { TW: { Aeternity: { Proto: { SigningInput: any; SigningOutput: any; }; }; Aion: { Proto: { SigningInput: any; SigningOutput: any; }; }; Algorand: { Proto: { AssetOptIn: any; AssetTransfer: any; SigningInput: any; SigningOutput: any; Transfer: any; }; }; Binance: { Proto: { CancelTradeOrder: any; ClaimHTLOrder: any; DepositHTLTOrder: any; HTLTOrder: any; RefundHTLTOrder: any; SendOrder: any; SideChainDelegate: any; SideChainRedelegate: any; SideChainUndelegate: any; Signature: any; SigningInput: any; SigningOutput: any; TimeLockOrder: any; TimeRelockOrder: any; TimeUnlockOrder: any; TokenBurnOrder: any; TokenFreezeOrder: any; TokenIssueOrder: any; TokenMintOrder: any; TokenUnfreezeOrder: any; TradeOrder: any; Transaction: any; TransferOut: any; }; }; Bitcoin: { Proto: { HashPublicKey: any; OutPoint: any; PreSigningOutput: any; SigningInput: any; SigningOutput: any; Transaction: any; TransactionInput: any; TransactionOutput: any; TransactionPlan: any; UnspentTransaction: any; }; }; Cardano: { Proto: { OutPoint: any; SigningInput: any; SigningOutput: any; TokenAmount: any; TransactionPlan: any; Transfer: any; TxInput: any; TxOutput: any; }; }; Common: { Proto: { SigningError: { "0": string; "1": string; "10": string; "11": string; "12": string; "13": string; "14": string; "15": string; "16": string; "17": string; "18": string; "19": string; "2": string; "20": string; "21": string; "22": string; "3": string; "4": string; "5": string; "6": string; "7": string; "8": string; "9": string; Error_general: number; Error_input_parse: number; Error_internal: number; Error_invalid_address: number; Error_invalid_memo: number; Error_invalid_params: number; Error_invalid_private_key: number; Error_invalid_utxo: number; Error_invalid_utxo_amount: number; Error_low_balance: number; Error_missing_input_utxos: number; Error_missing_private_key: number; Error_no_support_n2n: number; Error_not_enough_utxos: number; Error_script_output: number; Error_script_redeem: number; Error_script_witness_program: number; Error_signatures_count: number; Error_signing: number; Error_tx_too_big: number; Error_wrong_fee: number; Error_zero_amount_requested: number; OK: number; }; }; }; Cosmos: { Proto: { Amount: any; BroadcastMode: { "0": string; "1": string; "2": string; ASYNC: number; BLOCK: number; SYNC: number; }; Fee: any; Height: any; Message: any; SigningInput: any; SigningMode: { "0": string; "1": string; JSON: number; Protobuf: number; }; SigningOutput: any; }; }; Decred: { Proto: { SigningOutput: any; Transaction: any; TransactionInput: any; TransactionOutput: any; }; }; EOS: { Proto: { Asset: any; KeyType: { "0": string; "1": string; "2": string; LEGACY: number; MODERNK1: number; MODERNR1: number; }; SigningInput: any; SigningOutput: any; }; }; Elrond: { Proto: { Accounts: any; EGLDTransfer: any; ESDTNFTTransfer: any; ESDTTransfer: any; GenericAction: any; SigningInput: any; SigningOutput: any; }; }; Ethereum: { Proto: { SigningInput: any; SigningOutput: any; Transaction: any; TransactionMode: { "0": string; "1": string; Enveloped: number; Legacy: number; }; }; }; FIO: { Proto: { Action: any; ChainParams: any; NewFundsContent: any; PublicAddress: any; SigningInput: any; SigningOutput: any; }; }; Filecoin: { Proto: { SigningInput: any; SigningOutput: any; }; }; Harmony: { Proto: { CommissionRate: any; Decimal: any; Description: any; DirectiveCollectRewards: any; DirectiveCreateValidator: any; DirectiveDelegate: any; DirectiveEditValidator: any; DirectiveUndelegate: any; SigningInput: any; SigningOutput: any; StakingMessage: any; TransactionMessage: any; }; }; Icon: { Proto: { SigningInput: any; SigningOutput: any; }; }; IoTeX: { Proto: { Action: any; ActionCore: any; ContractCall: any; SigningInput: any; SigningOutput: any; Staking: any; Transfer: any; }; }; NEAR: { Proto: { AccessKey: any; Action: any; AddKey: any; CreateAccount: any; DeleteAccount: any; DeleteKey: any; DeployContract: any; FullAccessPermission: any; FunctionCall: any; FunctionCallPermission: any; PublicKey: any; SigningInput: any; SigningOutput: any; Stake: any; Transfer: any; }; }; NEO: { Proto: { SigningInput: any; SigningOutput: any; TransactionInput: any; TransactionOutput: any; TransactionOutputPlan: any; TransactionPlan: any; }; }; NULS: { Proto: { Signature: any; SigningInput: any; SigningOutput: any; Transaction: any; TransactionCoinFrom: any; TransactionCoinTo: any; }; }; Nano: { Proto: { SigningInput: any; SigningOutput: any; }; }; Nebulas: { Proto: { Data: any; RawTransaction: any; SigningInput: any; SigningOutput: any; }; }; Nimiq: { Proto: { SigningInput: any; SigningOutput: any; }; }; Oasis: { Proto: { SigningInput: any; SigningOutput: any; TransferMessage: any; }; }; Ontology: { Proto: { SigningInput: any; SigningOutput: any; }; }; Polkadot: { Proto: { Balance: any; Era: any; Network: { "0": string; "2": string; KUSAMA: number; POLKADOT: number; }; RewardDestination: { "0": string; "1": string; "2": string; CONTROLLER: number; STAKED: number; STASH: number; }; SigningInput: any; SigningOutput: any; Staking: any; }; }; Ripple: { Proto: { SigningInput: any; SigningOutput: any; }; }; Solana: { Proto: { CreateAndTransferToken: any; CreateTokenAccount: any; DeactivateAllStake: any; DeactivateStake: any; DelegateStake: any; SigningInput: any; SigningOutput: any; StakeAccountValue: any; TokenTransfer: any; Transfer: any; WithdrawAllStake: any; WithdrawStake: any; }; }; Stellar: { Proto: { Asset: any; ClaimPredicate: { "0": string; Predicate_unconditional: number; }; Claimant: any; MemoHash: any; MemoId: any; MemoText: any; MemoVoid: any; OperationChangeTrust: any; OperationClaimClaimableBalance: any; OperationCreateAccount: any; OperationCreateClaimableBalance: any; OperationPayment: any; SigningInput: any; SigningOutput: any; }; }; THORChainSwap: { Proto: { Asset: any; Chain: { "0": string; "1": string; "2": string; "3": string; BNB: number; BTC: number; ETH: number; THOR: number; }; Error: any; ErrorCode: { "0": string; "1": string; "13": string; "14": string; "15": string; "16": string; "2": string; "21": string; "22": string; Error_Input_proto_deserialization: number; Error_Invalid_from_address: number; Error_Invalid_router_address: number; Error_Invalid_to_address: number; Error_Invalid_vault_address: number; Error_Unsupported_from_chain: number; Error_Unsupported_to_chain: number; Error_general: number; OK: number; }; SwapInput: any; SwapOutput: any; }; }; Tezos: { Proto: { DelegationOperationData: any; Operation: any; OperationList: any; RevealOperationData: any; SigningInput: any; SigningOutput: any; TransactionOperationData: any; }; }; Theta: { Proto: { SigningInput: any; SigningOutput: any; }; }; Tron: { Proto: { BlockHeader: any; FreezeBalanceContract: any; SigningInput: any; SigningOutput: any; Transaction: any; TransferAssetContract: any; TransferContract: any; TransferTRC20Contract: any; TriggerSmartContract: any; UnfreezeAssetContract: any; UnfreezeBalanceContract: any; VoteAssetContract: any; VoteWitnessContract: any; WithdrawBalanceContract: any; }; }; TxCompiler: { Proto: { PreSigningOutput: any; }; }; VeChain: { Proto: { Clause: any; SigningInput: any; SigningOutput: any; }; }; Waves: { Proto: { CancelLeaseMessage: any; LeaseMessage: any; SigningInput: any; SigningOutput: any; TransferMessage: any; }; }; Zilliqa: { Proto: { SigningInput: any; SigningOutput: any; Transaction: any; }; }; }; WalletCore: { BindingError: any; InternalError: any; UnboundTypeError: any; count_emval_handles: any; dynCall_iiiiiijj: any; dynCall_iiiiij: any; dynCall_iiiiijj: any; dynCall_iiiij: any; dynCall_iiij: any; dynCall_iiiji: any; dynCall_iiji: any; dynCall_ji: any; dynCall_jii: any; dynCall_jiii: any; dynCall_jiiii: any; dynCall_jij: any; dynCall_jiji: any; dynCall_jijjj: any; dynCall_jj: any; dynCall_viiiijijji: any; dynCall_viijii: any; dynCall_viji: any; flushPendingDeletes: any; getInheritedInstanceCount: any; getLiveInheritedInstances: any; get_first_emval: any; inspect: any; run: any; setDelayFunction: any; }; }; ```

Although I might have done something wrong but I think we could use the templates you attached to generate the .d.ts typings but also be on the safe side because as you can see the package has casted everything as any which means the typesafety would be lost.

Also, I would like to hear your thoughts on this too.

Thanks.

hewigovens commented 2 years ago

Thanks for the test, wallet-core.js will load .wasm and export those generated methods, I don't think dts-gen is awares of this case. Codegen the typed info is still needed

foogazy commented 2 years ago

Hello! That's true, I don't think the dts-gen package is aware of this. Also, while searching for solutions, I found this issue which had some suggestions however I was not able to generate the types using the tools mentioned (feel free to test it as I might have mistaken some stuff). So, should I start with the erb templates above to generate typedefs?

hewigovens commented 2 years ago

Yeah, if you need help, feel free to contact us in https://t.me/trust_developers

hewigovens commented 2 years ago

@foogazy have you started? if not we will try to implement it from this week

foogazy commented 2 years ago

@hewigovens Hello there! Hope you're well. Sorry about the delay, I was literally buried under work. I'll check out the draft and help with whatever I can.

hewigovens commented 2 years ago

That's fine, I already created a pull request, will finish it this week

foogazy commented 2 years ago

@hewigovens You are literally amazing! Thank you so much for all your efforts for this amazing project! Once my contract for this job finishes, I will come back and help with anything I can offer for this project.