cosmjs icon indicating copy to clipboard operation
cosmjs copied to clipboard

How can I send an osmosis swap transaction?

Open 0xphilipp opened this issue 4 years ago • 6 comments

Hi,

I'm currently somehow lost in how to use the cosmjs library. I tried a lot of combinations, but I can't sign and broadcast a osmosis swap transaction.

What I already tried:

  1. Using Stargate Client
		const wallet = await DirectSecp256k1HdWallet.fromMnemonic(this.mnemonic, { prefix: 'osmo' });

		const rpcOsmo = 'https://rpc-osmosis.keplr.app';

		const registry = new Registry([
			...defaultRegistryTypes,
			['/osmosis/gamm/swap-exact-amount-in', MsgSwapExactAmountIn], 
			['osmosis/gamm/swap-exact-amount-in', MsgSwapExactAmountIn], // tried both as typeUrl but both get an error
		]);

		const osmoClient = await SigningStargateClient.connectWithSigner(rpcOsmo, wallet, {
			registry: registry,
		});

msg.ts msg.proto

this.osmoClient.signAndBroadcast(
			this.osmoAccount.address,
			[
				{
					typeUrl: '/osmosis/gamm/swap-exact-amount-in',
					value: {
						sender: 'osmo...',
						routes: [
							{
								poolId: '1',
								tokenOutDenom: 'ATOM',
							},
						],
						tokenIn: {
							denom: 'OSMO',
							amount: '123',
						},
						tokenOutMinAmount: '123',
					},
				},
			],
			{
				gas: '1000000',
				amount: [
					{
						amount: '0',
						denom: 'uosmos',
					},
				],
			},
			''
		);

-> TypeError: message.poolId.isZero is not a function

this.osmoClient.signAndBroadcast(
			this.osmoAccount.address,
			[
				{
					typeUrl: '/osmosis/gamm/swap-exact-amount-in',
					value: MsgSwapExactAmountIn.fromPartial({
						sender: 'osmo...',
						routes: [
							{
								poolId: Long.fromNumber(1),
								tokenOutDenom: 'ATOM',
							},
						],
						tokenIn: {
							denom: 'OSMO',
							amount: '123',
						},
						tokenOutMinAmount: '123',
					}),
				},
			],
			{
				gas: '1000000',
				amount: [
					{
						amount: '0',
						denom: 'uosmos',
					},
				],
			},
			''
		);

-> Broadcasting transaction failed with code 2 (codespace: sdk). Log: unable to resolve type URL /osmosis/gamm/swap-exact-amount-in: tx parse error So it looks like the rpc endpoint of keplr app does not support this type. Looking at the keplr wallet it looks like they use the old client: SigningCosmosClient

  1. Second try with the old client

		const walletCosmos = await Secp256k1HdWallet.fromMnemonic(this.mnemonic, undefined, 'osmo');
		const accountsOsmoCosmos = await walletCosmos.getAccounts();
		const lcdOsmo = 'https://lcd-osmosis.keplr.app'; // with the rpc endpoint again errors
		const osmoCosmosClient = new SigningCosmosClient(lcdOsmo, this.osmoAccountCosmos.address, walletCosmos);

this.osmoCosmosClient.signAndBroadcast(
			[
				{
					type: 'osmosis/gamm/swap-exact-amount-in',
					value: {
						sender: 'osmo...',
						routes: [
							{
								poolId: Long.fromNumber(1),
								tokenOutDenom: 'ATOM',
							},
						],
						tokenIn: {
							denom: 'OSMO',
							amount: '123',
						},
						tokenOutMinAmount: '123',
					},
				},
			],
			{
				gas: '1000000',
				amount: [
					{
						amount: '0',
						denom: 'uosmos',
					},
				],
			},
			''
		);

->

auth.js:11 Uncaught (in promise) Error: Unexpected response data format
    at Object.account (auth.js:11)
    at async SigningCosmosClient.getAccount (cosmosclient.js:100)
    at async SigningCosmosClient.getSequence (cosmosclient.js:90)
    at async SigningCosmosClient.sign (signingcosmosclient.js:67)
    at async SigningCosmosClient.signAndBroadcast (signingcosmosclient.js:59)
{
   "height":"1817054",
   "result":{
      "type":"cosmos-sdk/BaseAccount",
      "value":{
         "address":"osmo...",
         "public_key":{
            "type":"tendermint/PubKeySecp256k1",
            "value":"..."
         },
         "account_number":"...",
         "sequence":"..."
      }
   }
}

As far as I understand is BaseAccount type not supported by the SigningCosmosClient. Does anyone has a running example for custom types?

0xphilipp avatar Nov 01 '21 09:11 0xphilipp

@Phmager you can look at custom protocodecs - https://github.com/cosmos/cosmjs/blob/main/packages/stargate/CUSTOM_PROTOBUF_CODECS.md

puneet2019 avatar Dec 16 '21 09:12 puneet2019

I tried with custom type but got same error Broadcasting transaction failed with code 2 (codespace: sdk). Log: unable to resolve type URL /osmosis/gamm/swap-exact-amount-in: tx parse error.

tandn37 avatar Jan 18 '22 08:01 tandn37

nvm, found the new tx url from osmosis repo, @Phmager it should be /osmosis.gamm.v1beta1.MsgSwapExactAmountIn

tandn37 avatar Jan 18 '22 09:01 tandn37

As far as I understand is BaseAccount type not supported [..]

CosmJS only supports connecting to Tendermint RPC for all current backends. The clients from @cosmjs/stargate need to be used. The LCD client in @cosmjs/launchpad was only used for Cosmos SDK 0.37-0.39 chains and will be removed in the next version of CosmJS.

webmaster128 avatar Jan 21 '22 14:01 webmaster128

https://github.com/cosmology-finance/cosmology/tree/master/packages/core#swapexactamountin

I've documented it here. This uses cosmjs but does a lot to manage the registry, etc.

pyramation avatar Apr 18 '22 02:04 pyramation

Hi,

I'm currently somehow lost in how to use the cosmjs library. I tried a lot of combinations, but I can't sign and broadcast a osmosis swap transaction.

What I already tried:

  1. Using Stargate Client
		const wallet = await DirectSecp256k1HdWallet.fromMnemonic(this.mnemonic, { prefix: 'osmo' });

		const rpcOsmo = 'https://rpc-osmosis.keplr.app';

		const registry = new Registry([
			...defaultRegistryTypes,
			['/osmosis/gamm/swap-exact-amount-in', MsgSwapExactAmountIn], 
			['osmosis/gamm/swap-exact-amount-in', MsgSwapExactAmountIn], // tried both as typeUrl but both get an error
		]);

		const osmoClient = await SigningStargateClient.connectWithSigner(rpcOsmo, wallet, {
			registry: registry,
		});

msg.ts msg.proto

this.osmoClient.signAndBroadcast(
			this.osmoAccount.address,
			[
				{
					typeUrl: '/osmosis/gamm/swap-exact-amount-in',
					value: {
						sender: 'osmo...',
						routes: [
							{
								poolId: '1',
								tokenOutDenom: 'ATOM',
							},
						],
						tokenIn: {
							denom: 'OSMO',
							amount: '123',
						},
						tokenOutMinAmount: '123',
					},
				},
			],
			{
				gas: '1000000',
				amount: [
					{
						amount: '0',
						denom: 'uosmos',
					},
				],
			},
			''
		);

-> TypeError: message.poolId.isZero is not a function

this.osmoClient.signAndBroadcast(
			this.osmoAccount.address,
			[
				{
					typeUrl: '/osmosis/gamm/swap-exact-amount-in',
					value: MsgSwapExactAmountIn.fromPartial({
						sender: 'osmo...',
						routes: [
							{
								poolId: Long.fromNumber(1),
								tokenOutDenom: 'ATOM',
							},
						],
						tokenIn: {
							denom: 'OSMO',
							amount: '123',
						},
						tokenOutMinAmount: '123',
					}),
				},
			],
			{
				gas: '1000000',
				amount: [
					{
						amount: '0',
						denom: 'uosmos',
					},
				],
			},
			''
		);

-> Broadcasting transaction failed with code 2 (codespace: sdk). Log: unable to resolve type URL /osmosis/gamm/swap-exact-amount-in: tx parse error So it looks like the rpc endpoint of keplr app does not support this type. Looking at the keplr wallet it looks like they use the old client: SigningCosmosClient

  1. Second try with the old client
		const walletCosmos = await Secp256k1HdWallet.fromMnemonic(this.mnemonic, undefined, 'osmo');
		const accountsOsmoCosmos = await walletCosmos.getAccounts();
		const lcdOsmo = 'https://lcd-osmosis.keplr.app'; // with the rpc endpoint again errors
		const osmoCosmosClient = new SigningCosmosClient(lcdOsmo, this.osmoAccountCosmos.address, walletCosmos);

this.osmoCosmosClient.signAndBroadcast(
			[
				{
					type: 'osmosis/gamm/swap-exact-amount-in',
					value: {
						sender: 'osmo...',
						routes: [
							{
								poolId: Long.fromNumber(1),
								tokenOutDenom: 'ATOM',
							},
						],
						tokenIn: {
							denom: 'OSMO',
							amount: '123',
						},
						tokenOutMinAmount: '123',
					},
				},
			],
			{
				gas: '1000000',
				amount: [
					{
						amount: '0',
						denom: 'uosmos',
					},
				],
			},
			''
		);

->

auth.js:11 Uncaught (in promise) Error: Unexpected response data format
    at Object.account (auth.js:11)
    at async SigningCosmosClient.getAccount (cosmosclient.js:100)
    at async SigningCosmosClient.getSequence (cosmosclient.js:90)
    at async SigningCosmosClient.sign (signingcosmosclient.js:67)
    at async SigningCosmosClient.signAndBroadcast (signingcosmosclient.js:59)
{
   "height":"1817054",
   "result":{
      "type":"cosmos-sdk/BaseAccount",
      "value":{
         "address":"osmo...",
         "public_key":{
            "type":"tendermint/PubKeySecp256k1",
            "value":"..."
         },
         "account_number":"...",
         "sequence":"..."
      }
   }
}

As far as I understand is BaseAccount type not supported by the SigningCosmosClient. Does anyone has a running example for custom types?

Did you fix it?

dinhquocnghi avatar Nov 01 '22 01:11 dinhquocnghi