Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix IBC transfers from the cosmjs-type upgrade #108

Merged
merged 1 commit into from
Jan 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
105,829 changes: 53,618 additions & 52,211 deletions v4-client-js/__native__/__ios__/v4-native-client.js

Large diffs are not rendered by default.

Binary file not shown.
6 changes: 3 additions & 3 deletions v4-client-js/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions v4-client-js/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@dydxprotocol/v4-client-js",
"version": "1.0.13",
"version": "1.0.14",
"description": "General client library for the new dYdX system (v4 decentralized)",
"main": "build/src/index.js",
"scripts": {
Expand Down Expand Up @@ -44,6 +44,7 @@
"axios": "1.1.3",
"bech32": "^1.1.4",
"bignumber.js": "^9.1.1",
"cosmjs-types": "^0.9.0",
"ethereum-cryptography": "^2.0.0",
"ethers": "^6.6.1",
"long": "^4.0.0",
Expand All @@ -64,7 +65,6 @@
"babel-preset-es2015": "^6.24.1",
"browserify-zlib": "^0.2.0",
"buffer": "^6.0.3",
"cosmjs-types": "^0.9.0",
"crypto-browserify": "^3.12.0",
"grpc-tools": "^1.12.4",
"https-browserify": "^1.0.0",
Expand Down
54 changes: 39 additions & 15 deletions v4-client-js/src/clients/native.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
Native app can call JS functions with primitives.
*/

import { EncodeObject } from '@cosmjs/proto-signing';
import { accountFromAny } from '@cosmjs/stargate';
import { EncodeObject, coin as createCoin } from '@cosmjs/proto-signing';
import { MsgTransferEncodeObject, accountFromAny } from '@cosmjs/stargate';
import { Order_Side, Order_TimeInForce } from '@dydxprotocol/v4-proto/src/codegen/dydxprotocol/clob/order';
import * as AuthModule from 'cosmjs-types/cosmos/auth/v1beta1/query';
import Long from 'long';
Expand All @@ -21,7 +21,7 @@ import { FaucetClient } from './faucet-client';
import LocalWallet from './modules/local-wallet';
import { NobleClient } from './noble-client';
import { SubaccountInfo } from './subaccount';
import { OrderFlags } from './types';
import { OrderFlags, SquidIBCPayload } from './types';

declare global {
// eslint-disable-next-line vars-on-top, no-var
Expand Down Expand Up @@ -475,11 +475,17 @@ export async function withdrawToIBC(
const decode = (str: string):string => Buffer.from(str, 'base64').toString('binary');
const decoded = decode(payload);

const json = JSON.parse(decoded);
const json: SquidIBCPayload = JSON.parse(decoded);

const ibcMsg: EncodeObject = {
const ibcMsg: MsgTransferEncodeObject = {
typeUrl: json.msgTypeUrl, // '/ibc.applications.transfer.v1.MsgTransfer',
value: json.msg,
value: {
...json.msg,
// Squid returns timeoutTimestamp as Long, but the signer expects BigInt
timeoutTimestamp: json.msg.timeoutTimestamp
? BigInt(Long.fromValue(json.msg.timeoutTimestamp).toString())
: undefined,
},
};

const subaccount = new SubaccountInfo(wallet, subaccountNumber);
Expand Down Expand Up @@ -1041,14 +1047,26 @@ export async function sendNobleIBC(squidPayload: string): Promise<String> {
);
}

const json = JSON.parse(squidPayload);
const json: SquidIBCPayload = JSON.parse(squidPayload);

const ibcMsg: EncodeObject = {
typeUrl: json.msgTypeUrl, // '/ibc.applications.transfer.v1.MsgTransfer',
value: json.msg,
const ibcMsg: MsgTransferEncodeObject = {
typeUrl: json.msgTypeUrl,
value: {
...json.msg,
// Squid returns timeoutTimestamp as Long, but the signer expects BigInt
timeoutTimestamp: json.msg.timeoutTimestamp
? BigInt(Long.fromValue(json.msg.timeoutTimestamp).toString())
: undefined,
},
};
const fee = await client.simulateTransaction([ibcMsg]);

if (!ibcMsg.value.token) {
throw new UserError(
'Payload missing token field',
);
}

// take out fee from amount before sweeping
const amount = parseInt(ibcMsg.value.token.amount, 10) -
Math.floor(parseInt(fee.amount[0].amount, 10) * GAS_MULTIPLIER);
Expand All @@ -1057,8 +1075,8 @@ export async function sendNobleIBC(squidPayload: string): Promise<String> {
throw new UserError('noble balance does not cover fees');
}

ibcMsg.value.token.amount = amount.toString();
const tx = await client.send([ibcMsg]);
ibcMsg.value.token = createCoin(amount.toString(), ibcMsg.value.token.denom);
const tx = await client.IBCTransfer(ibcMsg);
return encodeJson(tx);
} catch (error) {
return wrappedError(error);
Expand All @@ -1082,15 +1100,21 @@ export async function withdrawToNobleIBC(payload: string): Promise<String> {
const decode = (str: string):string => Buffer.from(str, 'base64').toString('binary');
const decoded = decode(ibcPayload);

const parsedIbcPayload = JSON.parse(decoded);
const parsedIbcPayload: SquidIBCPayload = JSON.parse(decoded);

const msg = client.withdrawFromSubaccountMessage(
new SubaccountInfo(wallet, subaccountNumber),
parseFloat(amount).toFixed(client.validatorClient.config.denoms.USDC_DECIMALS),
);
const ibcMsg: EncodeObject = {
const ibcMsg: MsgTransferEncodeObject = {
typeUrl: parsedIbcPayload.msgTypeUrl,
value: parsedIbcPayload.msg,
value: {
...parsedIbcPayload.msg,
// Squid returns timeoutTimestamp as Long, but the signer expects BigInt
timeoutTimestamp: parsedIbcPayload.msg.timeoutTimestamp
? BigInt(Long.fromValue(json.msg.timeoutTimestamp).toString())
: undefined,
},
};

const tx = await client.send(
Expand Down
6 changes: 6 additions & 0 deletions v4-client-js/src/clients/noble-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
StdFee,
defaultRegistryTypes,
SigningStargateClient,
MsgTransferEncodeObject,
} from '@cosmjs/stargate';

import { GAS_MULTIPLIER } from './constants';
Expand Down Expand Up @@ -56,6 +57,11 @@ export class NobleClient {
return this.stargateClient.getBalance(this.wallet.address, denom);
}

async IBCTransfer(message: MsgTransferEncodeObject): Promise<DeliverTxResponse> {
const tx = await this.send([message]);
return tx;
}

async send(
messages: EncodeObject[],
gasPrice: GasPrice = GasPrice.fromString('0.025uusdc'),
Expand Down
14 changes: 14 additions & 0 deletions v4-client-js/src/clients/types.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { Coin } from '@cosmjs/proto-signing';
import { Method } from '@cosmjs/tendermint-rpc';
import { Order_ConditionType, Order_Side, Order_TimeInForce } from '@dydxprotocol/v4-proto/src/codegen/dydxprotocol/clob/order';
import BigNumber from 'bignumber.js';
Expand Down Expand Up @@ -95,4 +96,17 @@ export interface ComplianceResponse {
restricted: boolean;
}

export type SquidIBCPayload = {
msgTypeUrl: '/ibc.applications.transfer.v1.MsgTransfer';
msg: Partial<{
sourcePort: string;
sourceChannel: string;
token: Coin;
sender: string;
receiver: string;
timeoutTimestamp: Long;
memo: string;
}>;
};

export * from './modules/proto-includes';