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

update typescript abi #3475

Merged
merged 4 commits into from
Jan 9, 2025
Merged
Show file tree
Hide file tree
Changes from 3 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
31 changes: 15 additions & 16 deletions typescript-sdk/src/abi/ucs-03.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,28 +50,28 @@ export const ucs03ZkgmAbi = [
},
{
type: "function",
name: "SYSCALL_BATCH",
name: "OP_BATCH",
inputs: [],
outputs: [{ name: "", type: "uint8", internalType: "uint8" }],
stateMutability: "view"
},
{
type: "function",
name: "SYSCALL_FORWARD",
name: "OP_FORWARD",
inputs: [],
outputs: [{ name: "", type: "uint8", internalType: "uint8" }],
stateMutability: "view"
},
{
type: "function",
name: "SYSCALL_FUNGIBLE_ASSET_TRANSFER",
name: "OP_FUNGIBLE_ASSET_TRANSFER",
inputs: [],
outputs: [{ name: "", type: "uint8", internalType: "uint8" }],
stateMutability: "view"
},
{
type: "function",
name: "SYSCALL_MULTIPLEX",
name: "OP_MULTIPLEX",
inputs: [],
outputs: [{ name: "", type: "uint8", internalType: "uint8" }],
stateMutability: "view"
Expand Down Expand Up @@ -291,7 +291,7 @@ export const ucs03ZkgmAbi = [
name: "onRecvPacket",
inputs: [
{
name: "packet",
name: "operand",
type: "tuple",
internalType: "struct IBCPacket",
components: [
Expand Down Expand Up @@ -380,13 +380,13 @@ export const ucs03ZkgmAbi = [
{ name: "timeoutTimestamp", type: "uint64", internalType: "uint64" },
{ name: "salt", type: "bytes32", internalType: "bytes32" },
{
name: "syscallPacket",
name: "instruction",
type: "tuple",
internalType: "struct SyscallPacket",
internalType: "struct Instruction",
components: [
{ name: "version", type: "uint8", internalType: "uint8" },
{ name: "index", type: "uint8", internalType: "uint8" },
{ name: "packet", type: "bytes", internalType: "bytes" }
{ name: "opcode", type: "uint8", internalType: "uint8" },
{ name: "operand", type: "bytes", internalType: "bytes" }
]
}
],
Expand All @@ -405,15 +405,14 @@ export const ucs03ZkgmAbi = [
name: "transfer",
inputs: [
{ name: "channelId", type: "uint32", internalType: "uint32" },
{ name: "receiver", type: "bytes", internalType: "bytes" },
{ name: "baseToken", type: "address", internalType: "address" },
{ name: "baseAmount", type: "uint256", internalType: "uint256" },
{ name: "quoteToken", type: "bytes", internalType: "bytes" },
{ name: "quoteAmount", type: "uint256", internalType: "uint256" },
{ name: "timeoutHeight", type: "uint64", internalType: "uint64" },
{ name: "timeoutTimestamp", type: "uint64", internalType: "uint64" },
{ name: "salt", type: "bytes32", internalType: "bytes32" },
{ name: "receiver", type: "bytes", internalType: "bytes" },
{ name: "sentToken", type: "address", internalType: "address" },
{ name: "sentAmount", type: "uint256", internalType: "uint256" },
{ name: "askToken", type: "bytes", internalType: "bytes" },
{ name: "askAmount", type: "uint256", internalType: "uint256" },
{ name: "onlyMaker", type: "bool", internalType: "bool" }
{ name: "salt", type: "bytes32", internalType: "bytes32" }
],
outputs: [],
stateMutability: "nonpayable"
Expand Down
45 changes: 10 additions & 35 deletions typescript-sdk/src/evm/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,23 +72,12 @@ export const createEvmClient = (parameters: EvmClientParameters) => {
denomAddress,
simulate = true,
destinationChainId,
autoApprove = false,
relayContractAddress
autoApprove = false
}: TransferAssetsParameters<EvmChainId>): Promise<Result<Hex, Error>> => {
account ||= client.account
console.log(`EVM client created for chainId: ${parameters.chainId}`)
// first check if chain ids are the same, if yes then we can skip the hubble check and do a simple erc20 transfer
// if (parameters.chainId === destinationChainId) {
// const transfer = await evmSameChainTransfer(client, {
// amount,
// account,
// simulate,
// receiver,
// denomAddress
// })
// if (transfer.isErr()) return err(transfer.error)
// return ok(transfer.value)
// }

const baseToken = denomAddress

const chainDetails = await getHubbleChainDetails({
sourceChainId: parameters.chainId,
Expand All @@ -105,41 +94,27 @@ export const createEvmClient = (parameters: EvmClientParameters) => {

// We need to predict the askToken denom based on the sentToken (denomAddress in the transferAssetFromEvm args)
// we do this by calling the ucs03 instance on the counterparty chain.
const [askToken, _] = (await destinationChainClient.readContract({
const [quoteToken, _] = (await destinationChainClient.readContract({
address: chainDetails.value.destinationUCS03Address as `0x${string}`,
abi: ucs03ZkgmAbi,
functionName: "predictWrappedToken",
args: [0, chainDetails.value.destinationChannel, denomAddress]
args: [0, chainDetails.value.destinationChannel, baseToken]
})) as ["0x${string}", string]

console.log({ sentToken: denomAddress, askToken }) // useful for debugging app

// if (chainDetails.value.transferType === "pfm") {
// if (!chainDetails.value.port) return err(new Error("Port not found in hubble"))
// const pfmMemo = createPfmMemo({
// channel: chainDetails.value.destinationChannel,
// port: chainDetails.value.port,
// receiver: cosmosChainId.includes(destinationChainId)
// ? bech32AddressToHex({ address: receiver })
// : receiver
// })

// if (pfmMemo.isErr()) return err(pfmMemo.error)
// memo = pfmMemo.value
// }
console.log({ baseToken, quoteToken }) // useful for debugging app

const sourceChannel = chainDetails.value.sourceChannel
relayContractAddress ??= getAddress(chainDetails.value.relayContractAddress)
const relayContractAddress = getAddress(chainDetails.value.relayContractAddress)

return await transferAssetFromEvm(client, {
memo,
amount,
baseAmount: amount,
account,
simulate,
receiver,
autoApprove,
denomAddress,
askToken,
baseToken,
quoteToken,
sourceChannel,
relayContractAddress
})
Expand Down
73 changes: 39 additions & 34 deletions typescript-sdk/src/evm/transfer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,14 @@ import {

export type EvmTransferParams = {
memo?: string
askToken: HexAddress
amount: bigint
baseAmount: bigint
receiver: string
account?: Account
simulate?: boolean
autoApprove?: boolean
sourceChannel: number
denomAddress: HexAddress
baseToken: HexAddress
quoteToken: HexAddress
relayContractAddress: HexAddress
}

Expand All @@ -45,11 +45,11 @@ export async function transferAssetFromEvm(
client: WalletClient & PublicActions,
{
memo,
amount,
baseAmount,
account,
receiver,
denomAddress,
askToken,
baseToken,
quoteToken,
sourceChannel,
simulate = true,
autoApprove = false,
Expand All @@ -59,27 +59,31 @@ export async function transferAssetFromEvm(
account ||= client.account
if (!account) return err(new Error("No account found"))

denomAddress = getAddress(denomAddress)
// baseToken = getAddress(baseToken)
/* lowercasing because for some reason our ucs01 contract only likes lowercase address */
relayContractAddress = getAddress(relayContractAddress).toLowerCase() as HexAddress

if (autoApprove) {
const approveResponse = await evmApproveTransferAsset(client, {
amount,
amount: baseAmount,
account,
denomAddress,
denomAddress: baseToken,
receiver: relayContractAddress
})
if (approveResponse.isErr()) return approveResponse
}

memo ??= timestamp()

// we want the same amount on dest as we send on the source
const quoteAmount = baseAmount

// add a salt to each transfer to prevent hash collisions
// important because ibc-union does not use sequence numbers
// such that intents are possible based on deterministic packet hashes
const salt = new Uint8Array(32)
crypto.getRandomValues(salt)
const rawSalt = new Uint8Array(32)
crypto.getRandomValues(rawSalt)
const salt = toHex(rawSalt)
/**
* @dev
* `UCS03` zkgm contract `transfer` function:
Expand All @@ -92,28 +96,26 @@ export async function transferAssetFromEvm(
functionName: "transfer",
address: relayContractAddress,
/**
* uint32 channelId,
* uint64 timeoutHeight,
* uint64 timeoutTimestamp,
* bytes32 salt,
* bytes calldata receiver,
* address sentToken,
* uint256 sentAmount,
* bytes calldata askToken,
* uint256 askAmount,
* bool onlyMaker
"channelId": "uint32"
"receiver": "bytes"
"baseToken": "address"
"baseAmount": "uint256"
"quoteToken": "bytes"
"quoteAmount": "uint256"
"timeoutHeight": "uint64"
"timeoutTimestamp": "uint64"
"salt": "bytes32"
*/
args: [
sourceChannel,
receiver.startsWith("0x") ? getAddress(receiver) : bech32AddressToHex({ address: receiver }),
baseToken,
baseAmount,
quoteToken,
quoteAmount,
0n, // TODO: customize timeoutheight
"0x000000000000000000000000000000000000000000000000fffffffffffffffa", // TODO: make non-hexencoded timestamp
toHex(salt),
receiver.startsWith("0x") ? getAddress(receiver) : bech32AddressToHex({ address: receiver }),
denomAddress,
amount,
askToken,
amount, // we want the same amount on dest as we send on the source
false
salt
]
} as const
if (!simulate) {
Expand All @@ -127,10 +129,13 @@ export async function transferAssetFromEvm(
return ok(hash)
}

export type EvmApproveTransferParams = Pick<
EvmTransferParams,
"amount" | "account" | "simulate" | "denomAddress" | "receiver"
>
export type EvmApproveTransferParams = {
amount: bigint
account?: Account
receiver: HexAddress
denomAddress: HexAddress
simulate?: boolean
}

/**
* approve a transfer asset from evm
Expand Down Expand Up @@ -185,10 +190,10 @@ export async function evmApproveTransferAsset(
export async function evmSameChainTransfer(
client: WalletClient & PublicActions,
{
amount,
baseAmount: amount,
account,
receiver,
denomAddress,
baseToken: denomAddress,
simulate = true
}: Omit<EvmTransferParams, "memo" | "sourceChannel" | "relayContractAddress" | "autoApprove">
): Promise<Result<Hex, Error>> {
Expand Down
Loading