Skip to content
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
13 changes: 7 additions & 6 deletions packages/agent-sdk/examples/erc20transfer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
numberField,
validateInput,
type FieldParser,
signRequestFor,
} from "../src";

interface Input {
Expand Down Expand Up @@ -34,14 +35,14 @@ export async function GET(req: Request): Promise<Response> {
parsers,
);
const decimals = await getTokenDecimals(chainId, token);
const tx = erc20Transfer({
token,
to: recipient,
amount: parseUnits(amount.toString(), decimals),
});
return Response.json(
{
transaction: erc20Transfer({
chainId,
token,
to: recipient,
amount: parseUnits(amount.toString(), decimals),
}),
transaction: signRequestFor({ chainId, metaTransactions: [tx] }),
},
{ status: 200 },
);
Expand Down
63 changes: 25 additions & 38 deletions packages/agent-sdk/src/evm/erc20.ts
Original file line number Diff line number Diff line change
@@ -1,58 +1,45 @@
import { erc20Abi } from "viem";
import { encodeFunctionData, type Address } from "viem";
import { signRequestFor } from "..";
import { getClient, type SignRequestData } from "near-safe";
import { getClient, type MetaTransaction } from "near-safe";
import type { TokenInfo } from "./types";

const MAX_APPROVAL = BigInt(
"115792089237316195423570985008687907853269984665640564039457584007913129639935",
);

export async function erc20Transfer(params: {
chainId: number;
export function erc20Transfer(params: {
token: Address;
to: Address;
amount: bigint;
}): Promise<SignRequestData> {
const { chainId, token, to, amount } = params;
return signRequestFor({
chainId,
metaTransactions: [
{
to: token,
value: "0x",
data: encodeFunctionData({
abi: erc20Abi,
functionName: "transfer",
args: [to, amount],
}),
},
],
});
}): MetaTransaction {
const { token, to, amount } = params;
return {
to: token,
value: "0x0",
data: encodeFunctionData({
abi: erc20Abi,
functionName: "transfer",
args: [to, amount],
}),
};
}

export async function erc20Approve(params: {
chainId: number;
export function erc20Approve(params: {
token: Address;
spender: Address;
// If not provided, the maximum amount will be approved.
amount?: bigint;
}): Promise<SignRequestData> {
const { chainId, token, spender, amount } = params;
return signRequestFor({
chainId,
metaTransactions: [
{
to: token,
value: "0x",
data: encodeFunctionData({
abi: erc20Abi,
functionName: "approve",
args: [spender, amount ?? MAX_APPROVAL],
}),
},
],
});
}): MetaTransaction {
const { token, spender, amount } = params;
return {
to: token,
value: "0x0",
data: encodeFunctionData({
abi: erc20Abi,
functionName: "approve",
args: [spender, amount ?? MAX_APPROVAL],
}),
};
}

export async function checkAllowance(
Expand Down
3 changes: 2 additions & 1 deletion packages/agent-sdk/src/evm/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@ export function createResponse(
return {
json: (_data, responseInit) => ({
data: responseData,
...(responseInit ?? init),
...init,
...responseInit,
}),
};
}
Expand Down
23 changes: 1 addition & 22 deletions packages/agent-sdk/src/evm/weth.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Network, type MetaTransaction, type SignRequestData } from "near-safe";
import { Network, type MetaTransaction } from "near-safe";
import {
type Address,
encodeFunctionData,
Expand All @@ -7,7 +7,6 @@ import {
parseEther,
toHex,
} from "viem";
import { signRequestFor } from ".";

type NativeAsset = {
address: Address;
Expand Down Expand Up @@ -51,16 +50,6 @@ export function validateWethInput(params: URLSearchParams): {
};
}

export function unwrapSignRequest(
chainId: number,
amount: bigint,
): SignRequestData {
return signRequestFor({
chainId,
metaTransactions: [unwrapMetaTransaction(chainId, amount)],
});
}

export const unwrapMetaTransaction = (
chainId: number,
amount: bigint,
Expand All @@ -76,16 +65,6 @@ export const unwrapMetaTransaction = (
};
};

export function wrapSignRequest(
chainId: number,
amount: bigint,
): SignRequestData {
return signRequestFor({
chainId,
metaTransactions: [wrapMetaTransaction(chainId, amount)],
});
}

export const wrapMetaTransaction = (
chainId: number,
amount: bigint,
Expand Down
58 changes: 14 additions & 44 deletions packages/agent-sdk/tests/evm/erc20.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,76 +18,46 @@ describe("ERC20 Utilities", () => {
const mockAmount = 1000n;

describe("erc20Transfer", () => {
it("creates correct transfer transaction", async () => {
it("creates correct transfer transaction", () => {
const params = {
chainId: mockChainId,
token: mockAddress,
to: mockAddress,
amount: mockAmount,
};

const signRequest = await erc20Transfer(params);

expect(signRequest).toEqual({
chainId: 1,
method: "eth_sendTransaction",
params: [
{
data: "0xa9059cbb000000000000000000000000123456789012345678901234567890123456789000000000000000000000000000000000000000000000000000000000000003e8",
from: "0x0000000000000000000000000000000000000000",
to: "0x1234567890123456789012345678901234567890",
value: "0x",
},
],
expect(erc20Transfer(params)).toEqual({
data: "0xa9059cbb000000000000000000000000123456789012345678901234567890123456789000000000000000000000000000000000000000000000000000000000000003e8",
to: "0x1234567890123456789012345678901234567890",
value: "0x0",
});
});
});

describe("erc20Approve", () => {
it("creates approval transaction with specific amount", async () => {
const params = {
chainId: mockChainId,
token: mockAddress,
spender: mockAddress,
amount: mockAmount,
};

const signRequest = await erc20Approve(params);

expect(signRequest).toEqual({
chainId: 1,
method: "eth_sendTransaction",
params: [
{
data: "0x095ea7b3000000000000000000000000123456789012345678901234567890123456789000000000000000000000000000000000000000000000000000000000000003e8",
from: "0x0000000000000000000000000000000000000000",
to: "0x1234567890123456789012345678901234567890",
value: "0x",
},
],
expect(erc20Approve(params)).toEqual({
data: "0x095ea7b3000000000000000000000000123456789012345678901234567890123456789000000000000000000000000000000000000000000000000000000000000003e8",
to: "0x1234567890123456789012345678901234567890",
value: "0x0",
});
});

it("creates approval transaction with max amount when amount not specified", async () => {
it("creates approval transaction with max amount when amount not specified", () => {
const params = {
chainId: mockChainId,
token: mockAddress,
spender: mockAddress,
};

const signRequest = await erc20Approve(params);

expect(signRequest).toEqual({
chainId: 1,
method: "eth_sendTransaction",
params: [
{
data: "0x095ea7b30000000000000000000000001234567890123456789012345678901234567890ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
from: "0x0000000000000000000000000000000000000000",
to: "0x1234567890123456789012345678901234567890",
value: "0x",
},
],
expect(erc20Approve(params)).toEqual({
data: "0x095ea7b30000000000000000000000001234567890123456789012345678901234567890ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
to: "0x1234567890123456789012345678901234567890",
value: "0x0",
});
});
});
Expand Down
Loading