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

Build arbitrary Zkgm packets, show JSON interpetation, and recursively ethABI encode them #4088

Merged
merged 9 commits into from
Mar 20, 2025
Merged
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
2 changes: 1 addition & 1 deletion ts-sdk/examples/create-fungible-asset-order.ts
Original file line number Diff line number Diff line change
@@ -9,7 +9,7 @@ import {
createEvmToCosmosFungibleAssetOrder,
createCosmosToEvmFungibleAssetOrder,
createCosmosToCosmosFungibleAssetOrder
} from "../src/evm/ucs03/fungible-asset-order.js"
} from "../src/ucs03/fungible-asset-order.js"

import {
CosmWasmClientDestination,
23 changes: 23 additions & 0 deletions ts-sdk/examples/encode-packet.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { toHex } from "viem"
import { FungibleAssetOrder } from "../src/ucs03/instruction.js"
import { encodeZkgmPacketAbi, type ZkgmPacket } from "../src/ucs03/zkgm-packet.js"

const examplePacket: ZkgmPacket = {
salt: "0x1234567890123456789012345678901234567890123456789012345678901234",
path: 123456789n,
instruction: FungibleAssetOrder([
toHex("stars1qcvavxpxw3t8d9j7mwaeq9wgytkf5vwputv5x4"),
toHex("union1d95n4r6dnrfrps59szhl8mk7yqewsuzyw0zh5q"),
toHex("stars1qrde534d4jwk44dn7w7gu9e2rayutr7kqx8lfjhsk3rd7z9rzxhq2gh3lr"),
1000000n,
"WETH",
"WETH",
0,
0n,
"0x756e696f6e3170707865737461307064643038716537366779366b7438667563717978727a773076786a79366439767430676368357879707371656138377278",
1000000n
])
}

console.log("ZkgmPacket:", examplePacket)
console.log("Encoded:", encodeZkgmPacketAbi(examplePacket))
105 changes: 105 additions & 0 deletions ts-sdk/examples/ucs03.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import { toHex } from "viem"
import {
Batch,
encodeAbi,
Forward,
FungibleAssetOrder,
Multiplex
} from "../src/ucs03/instruction.js"

export const exampleBatchInstruction = Batch([
FungibleAssetOrder([
toHex("union1jk9psyhvgkrt2cumz8eytll2244m2nnz4yt2g2"),
"0xBe68fC2d8249eb60bfCf0e71D5A0d2F2e292c4eD",
toHex("muno"),
4n,
"muno",
"muno",
18,
0n,
"0x74d5b8eacfeb0dadaaf66403f40e304b3ef968b3",
4n
]),
FungibleAssetOrder([
toHex("union1jk9psyhvgkrt2cumz8eytll2244m2nnz4yt2g2"),
"0xBe68fC2d8249eb60bfCf0e71D5A0d2F2e292c4eD",
toHex("muno"),
4n,
"muno",
"muno",
18,
0n,
"0x74d5b8eacfeb0dadaaf66403f40e304b3ef968b3",
4n
])
])

export const exampleMultiplexInstruction = Multiplex([
"0xBe68fC2d8249eb60bfCf0e71D5A0d2F2e292c4eD",
true,
"0x74d5b8eacfeb0dadaaf66403f40e304b3ef968b3",
toHex("some smart contract data")
])

export const exampleForwardInstruction = Forward(
0n, // example path
0n, // example timeoutHeight
1234567890n, // example timeoutTimestamp
FungibleAssetOrder([
toHex("union1jk9psyhvgkrt2cumz8eytll2244m2nnz4yt2g2"),
"0xBe68fC2d8249eb60bfCf0e71D5A0d2F2e292c4eD",
toHex("muno"),
4n,
"muno",
"muno",
18,
0n,
"0x74d5b8eacfeb0dadaaf66403f40e304b3ef968b3",
4n
])
)

export const exampleTransferAndCall = Batch([
FungibleAssetOrder([
toHex("union1jk9psyhvgkrt2cumz8eytll2244m2nnz4yt2g2"),
"0xBe68fC2d8249eb60bfCf0e71D5A0d2F2e292c4eD",
toHex("muno"),
4n,
"muno",
"muno",
18,
0n,
"0x74d5b8eacfeb0dadaaf66403f40e304b3ef968b3",
4n
]),
Multiplex([
"0xBe68fC2d8249eb60bfCf0e71D5A0d2F2e292c4eD",
true,
"0x74d5b8eacfeb0dadaaf66403f40e304b3ef968b3",
toHex("some smart contract data")
]),
Forward(
0n,
10000000n,
0n,
Batch([
FungibleAssetOrder([
toHex("union1jk9psyhvgkrt2cumz8eytll2244m2nnz4yt2g2"),
"0xBe68fC2d8249eb60bfCf0e71D5A0d2F2e292c4eD",
toHex("muno"),
4n,
"muno",
"muno",
18,
0n,
"0x74d5b8eacfeb0dadaaf66403f40e304b3ef968b3",
4n
])
])
)
])

console.log(exampleBatchInstruction, encodeAbi(exampleBatchInstruction))
console.log(exampleMultiplexInstruction, encodeAbi(exampleMultiplexInstruction))
console.log(exampleForwardInstruction, encodeAbi(exampleForwardInstruction))
console.log(exampleTransferAndCall, encodeAbi(exampleTransferAndCall))
2 changes: 1 addition & 1 deletion ts-sdk/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@unionlabs/sdk",
"version": "1.3.0",
"version": "1.4.0",
"type": "module",
"license": "MIT",
"author": "@unionlabs",
1 change: 0 additions & 1 deletion ts-sdk/src/evm/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
export * as abi from "./abi/index.js"
export * as ucs03 from "./ucs03/index.js"
export * from "./contract.js"
export * from "./client.js"
export * from "./erc20.js"
48 changes: 0 additions & 48 deletions ts-sdk/src/evm/ucs03/index.ts

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { toHex, type Address, type Hex } from "viem"
import { Effect } from "effect"
import { ViemPublicClient, ViemPublicClientSource } from "../client.js"
import { readErc20Meta } from "../erc20.js"
import { predictQuoteToken as predictEvmQuoteToken } from "../quote-token.js"
import { CosmWasmClientContext, CosmWasmClientSource } from "../../cosmos/client.js"
import { readCw20TokenInfo } from "../../cosmos/cw20.js"
import { predictQuoteToken as predictCosmosQuoteToken } from "../../cosmos/quote-token.js"
import { ViemPublicClient, ViemPublicClientSource } from "../evm/client.js"
import { readErc20Meta } from "../evm/erc20.js"
import { predictQuoteToken as predictEvmQuoteToken } from "../evm/quote-token.js"
import { CosmWasmClientContext, CosmWasmClientSource } from "../cosmos/client.js"
import { readCw20TokenInfo } from "../cosmos/cw20.js"
import { predictQuoteToken as predictCosmosQuoteToken } from "../cosmos/quote-token.js"

export type FungibleAssetOrderIntent = {
sender: Address
1 change: 1 addition & 0 deletions ts-sdk/src/ucs03/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./instruction.js"
96 changes: 96 additions & 0 deletions ts-sdk/src/ucs03/instruction.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
import { encodeAbiParameters, type Hex } from "viem"
import { batchAbi, forwardAbi, fungibleAssetOrderAbi, multiplexAbi } from "../evm/abi/index.js"

export type Instruction = Forward | Multiplex | Batch | FungibleAssetOrder

export type Forward = {
opcode: 0
version: 0
operand: [bigint, bigint, bigint, Instruction]
}
export const Forward = (
path: bigint,
timeoutHeight: bigint,
timeoutTimestamp: bigint,
instruction: Instruction
): Forward => ({
opcode: 0,
version: 0,
operand: [path, timeoutHeight, timeoutTimestamp, instruction]
})

export type Multiplex = {
opcode: 1
version: 0
operand: Parameters<typeof encodeAbiParameters<typeof multiplexAbi>>[1]
}
export const Multiplex = (
operand: Parameters<typeof encodeAbiParameters<typeof multiplexAbi>>[1]
): Multiplex => ({
opcode: 1,
version: 0,
operand
})

export type Batch = {
opcode: 2
version: 0
operand: Array<Instruction>
}
export const Batch = (instructions: Array<Instruction>): Batch => ({
opcode: 2,
version: 0,
operand: instructions
})

export type FungibleAssetOrder = {
opcode: 3
version: 1
operand: Parameters<typeof encodeAbiParameters<typeof fungibleAssetOrderAbi>>[1]
}
export const FungibleAssetOrder = (
operand: Parameters<typeof encodeAbiParameters<typeof fungibleAssetOrderAbi>>[1]
): FungibleAssetOrder => ({
opcode: 3,
version: 1,
operand
})

export const encodeAbi = (instruction: Instruction): Hex => {
switch (instruction.opcode) {
case 0: {
// Forward
return encodeAbiParameters(forwardAbi, [
instruction.operand[0],
instruction.operand[1],
instruction.operand[2],
{
opcode: instruction.operand[3].opcode,
version: instruction.operand[3].version,
operand: encodeAbi(instruction.operand[3])
}
])
}
case 1: {
// Multiplex
return encodeAbiParameters(multiplexAbi, instruction.operand)
}
case 2: {
// Batch - recursively encode each instruction
return encodeAbiParameters(batchAbi, [
instruction.operand.map(instr => ({
version: instr.version,
opcode: instr.opcode,
operand: encodeAbi(instr)
}))
])
}
case 3: {
// FungibleAssetOrder
return encodeAbiParameters(fungibleAssetOrderAbi, instruction.operand)
}
default: {
throw new Error(`impossible`)
}
}
}
20 changes: 20 additions & 0 deletions ts-sdk/src/ucs03/zkgm-packet.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { encodeAbiParameters, type Hex } from "viem"
import { encodeAbi, type Instruction } from "./instruction.js"
import { zkgmPacketAbi } from "../evm/abi/index.js"

export type ZkgmPacket = {
salt: Hex
path: bigint
instruction: Instruction
}

export const encodeZkgmPacketAbi = (packet: ZkgmPacket) =>
encodeAbiParameters(zkgmPacketAbi, [
packet.salt,
packet.path,
{
opcode: packet.instruction.opcode,
version: packet.instruction.version,
operand: encodeAbi(packet.instruction)
}
])
25 changes: 0 additions & 25 deletions ts-sdk/test/evm.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { describe, it, expect } from "vitest"
import { ucs03abi, instructionAbi } from "../src/evm/abi/index.js"
import { Batch, FungibleAssetOrder } from "../src/evm/ucs03/index.js"

describe("abi", () => {
it("should export ucs03abi", () => {
@@ -23,27 +22,3 @@ describe("abi", () => {
expect(argNames).toContain("operand")
})
})

describe("ucs03", () => {
it("should encode FungibleAssetOrder and Batch correctly", () => {
const fungibleAssetOrder = FungibleAssetOrder([
"0xE6831e169d77a861A0E71326AFA6d80bCC8Bc6aA",
"0xE6831e169d77a861A0E71326AFA6d80bCC8Bc6aA",
"0x74d5b8eacfeb0dadaaf66403f40e304b3ef968b3",
4n,
"muno",
"muno",
18,
0n,
"0x74d5b8eacfeb0dadaaf66403f40e304b3ef968b3",
4n
])
const batch = Batch([fungibleAssetOrder, fungibleAssetOrder])
expect(batch).toStrictEqual({
opcode: 2,
version: 0,
operand:
"0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000038000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000002c00000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000001c000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000024000000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000014E6831e169d77a861A0E71326AFA6d80bCC8Bc6aA0000000000000000000000000000000000000000000000000000000000000000000000000000000000000014E6831e169d77a861A0E71326AFA6d80bCC8Bc6aA000000000000000000000000000000000000000000000000000000000000000000000000000000000000001474d5b8eacfeb0dadaaf66403f40e304b3ef968b300000000000000000000000000000000000000000000000000000000000000000000000000000000000000046d756e6f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000046d756e6f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001474d5b8eacfeb0dadaaf66403f40e304b3ef968b300000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000002c00000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000001c000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000024000000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000014E6831e169d77a861A0E71326AFA6d80bCC8Bc6aA0000000000000000000000000000000000000000000000000000000000000000000000000000000000000014E6831e169d77a861A0E71326AFA6d80bCC8Bc6aA000000000000000000000000000000000000000000000000000000000000000000000000000000000000001474d5b8eacfeb0dadaaf66403f40e304b3ef968b300000000000000000000000000000000000000000000000000000000000000000000000000000000000000046d756e6f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000046d756e6f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001474d5b8eacfeb0dadaaf66403f40e304b3ef968b3000000000000000000000000"
})
})
})
2 changes: 1 addition & 1 deletion ts-sdk/test/evm/fungible-asset-order.test.ts
Original file line number Diff line number Diff line change
@@ -9,7 +9,7 @@ import {
createEvmToCosmosFungibleAssetOrder,
createCosmosToEvmFungibleAssetOrder,
createCosmosToCosmosFungibleAssetOrder
} from "../../src/evm/ucs03/fungible-asset-order.js"
} from "../../src/ucs03/fungible-asset-order.js"
import { toHex } from "viem"

// Mock data for tests