Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit b8f5382

Browse files
committedMar 4, 2025
chore(app): creating aptos client according to wallet wip
Signed-off-by: Kaan Caglan <[email protected]>
1 parent 7a4a424 commit b8f5382

File tree

1 file changed

+125
-53
lines changed

1 file changed

+125
-53
lines changed
 

‎typescript-sdk/src/aptos/client.ts

+125-53
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,22 @@
11
import {
22
type AptosAccount,
3-
// (These below helpers remain as before)
43
waitForTransactionReceipt,
54
type AptosPublicAccountInfo
65
} from "./transfer.ts"
7-
import { err, type Result } from "neverthrow"
6+
import { ok, err, type Result } from "neverthrow"
87
import { Aptos, Network, AptosConfig, AccountAddress, MoveVector } from "@aptos-labs/ts-sdk"
98
import { createClient, fallback, type HttpTransport } from "viem"
109
import type { AptosBrowserWallet, AuthAccess } from "./wallet.ts"
1110

11+
// Define a unified signer type that always includes an accountAddress.
12+
export type AptosSigner = AptosAccount | (AptosBrowserWallet & { accountAddress: string })
13+
1214
export type { AptosAccount, AptosBrowserWallet }
1315

1416
export const aptosChainId = [
15-
"2", // aptos testnet
17+
"2", // aptos testnet
1618
"177", // movement porto
17-
"250" // movement bardock
19+
"250" // movement bardock
1820
] as const
1921
export type AptosChainId = `${(typeof aptosChainId)[number]}`
2022

@@ -31,23 +33,25 @@ export type AptosClientParameters = {
3133
| { account: AptosAccount; transport: HttpTransport }
3234
| { account?: AptosPublicAccountInfo; transport: AptosWindowTransport }
3335
)
36+
export type WalletSigner = AptosBrowserWallet & { accountAddress: string };
3437

3538
/**
3639
* Overloads for retrieving an Aptos client.
3740
*/
3841
async function getAptosClient(
3942
parameters: AptosClientParameters & { authAccess: "key" }
40-
): Promise<{ authAccess: "key"; aptos: Aptos; signer: AptosAccount }>
43+
): Promise<{ authAccess: "key"; aptos: Aptos; signer: AptosSigner; transport: HttpTransport }>;
44+
45+
async function getAptosClient(
46+
parameters: AptosClientParameters & { authAccess: "wallet" }
47+
): Promise<{ authAccess: "wallet"; aptos: Aptos; signer: AptosSigner; transport: AptosWindowTransport }>;
4148

42-
// async function getAptosClient(
43-
// parameters: AptosClientParameters & { authAccess: "wallet" }
44-
// ): Promise<{ authAccess: "wallet"; aptos: Aptos; signer: AptosBrowserWallet }>
4549

4650
async function getAptosClient(
4751
parameters: AptosClientParameters & { authAccess: AuthAccess }
4852
): Promise<
49-
| { authAccess: "key"; aptos: Aptos; signer: AptosAccount }
50-
| { authAccess: "wallet"; aptos: Aptos; signer: AptosBrowserWallet }
53+
| { authAccess: "key"; aptos: Aptos; signer: AptosSigner; transport: HttpTransport }
54+
| { authAccess: "wallet"; aptos: Aptos; signer: AptosSigner; transport: AptosWindowTransport }
5155
> {
5256
if (parameters.authAccess === "key") {
5357
if (typeof parameters.transport !== "function") {
@@ -62,7 +66,8 @@ async function getAptosClient(
6266
return {
6367
authAccess: "key",
6468
aptos: new Aptos(config),
65-
signer: parameters.account as AptosAccount
69+
signer: parameters.account as AptosAccount, // AptosAccount is assumed to have accountAddress
70+
transport: parameters.transport
6671
}
6772
}
6873

@@ -71,20 +76,36 @@ async function getAptosClient(
7176
throw new Error("Invalid Aptos transport")
7277
}
7378
const networkInfo = await parameters.transport.getNetwork()
74-
const network = networkInfo.name.toLowerCase() === "mainnet" ? Network.MAINNET : Network.TESTNET
79+
const network =
80+
networkInfo.name.toLowerCase() === "mainnet" ? Network.MAINNET : Network.TESTNET
7581
const config = new AptosConfig({ fullnode: networkInfo.url, network })
82+
83+
// Get the connected account
84+
const account = await parameters.transport.getAccount?.() ||
85+
{ address: "" }
86+
if (!account.address) {
87+
throw new Error("No account address found from the wallet")
88+
}
89+
90+
// Create a signer by merging the wallet’s methods with the account address.
91+
const signer = Object.assign({}, parameters.transport, {
92+
accountAddress: account.address
93+
}) as unknown as AptosAccount // <== Force-cast to AptosAccount
94+
7695
return {
7796
authAccess: "wallet",
7897
aptos: new Aptos(config),
79-
signer: parameters.transport as AptosBrowserWallet
98+
signer: signer,
99+
transport: parameters.transport
80100
}
81101
}
102+
103+
82104
throw new Error("Invalid Aptos transport")
83105
}
84106

85107
/**
86-
* New unified transfer parameters for Aptos,
87-
* matching the Cosmos & EVM clients.
108+
* New unified transfer parameters for Aptos, matching the Cosmos & EVM clients.
88109
*/
89110
export interface TransferAssetParameters<AptosChainId> {
90111
baseAmount: bigint
@@ -102,17 +123,22 @@ export interface TransferAssetParameters<AptosChainId> {
102123
*/
103124
export const createAptosClient = (clientParameters: AptosClientParameters) => {
104125
return createClient({ transport: fallback([]) })
105-
.extend(_ => ({
106-
// A helper to get the underlying Aptos client.
107-
// We default to "key" if an account was provided.
108-
getAptosClient: async () => await getAptosClient({ ...clientParameters, authAccess: "key" })
109-
// clientParameters.account
110-
// ? await getAptosClient({ ...clientParameters, authAccess: "key" })
111-
// : await getAptosClient({ ...clientParameters, authAccess: "wallet" })
126+
.extend(() => ({
127+
getAptosClient: async () => {
128+
console.info("create aptos client params:", clientParameters)
129+
// Use the transport type to determine which client to create.
130+
if (typeof clientParameters.transport === "function") {
131+
console.info("returning key-based client")
132+
return await getAptosClient({ ...clientParameters, authAccess: "key" })
133+
} else {
134+
console.info("returning wallet-based client")
135+
return await getAptosClient({ ...clientParameters, authAccess: "wallet" })
136+
}
137+
}
112138
}))
113139
.extend(client => ({
114140
waitForTransactionReceipt: async ({ hash }: { hash: string }) => {
115-
const { aptos, signer } = await client.getAptosClient()
141+
const { aptos } = await client.getAptosClient()
116142
return await waitForTransactionReceipt({ aptos, hash })
117143
},
118144

@@ -129,47 +155,93 @@ export const createAptosClient = (clientParameters: AptosClientParameters) => {
129155
sourceChannelId,
130156
ucs03address
131157
}: TransferAssetParameters<AptosChainId>): Promise<Result<string, Error>> => {
132-
const { aptos, signer } = await client.getAptosClient()
133-
134-
const baseTokenHex = baseToken.startsWith("0x") ? baseToken.slice(2) : baseToken // Remove "0x" if it exists
135-
// let my_addr = AccountAddress.fromHex(baseToken)
158+
const { aptos, signer, authAccess, transport } = await client.getAptosClient();
136159

137160
const quoteTokenVec = MoveVector.U8(quoteToken)
138161
const receiverVec = MoveVector.U8(receiver)
139162

140-
const rawSalt = new Uint8Array(32)
163+
const rawSalt = new Uint8Array(14)
141164
crypto.getRandomValues(rawSalt)
142165
const salt = MoveVector.U8(rawSalt)
143166

144-
const payload = await aptos.transaction.build.simple({
145-
sender: signer.accountAddress,
146-
data: {
147-
function: `${ucs03address}::ibc_app::transfer`,
148-
typeArguments: [],
149-
functionArguments: [
150-
sourceChannelId,
151-
receiverVec,
152-
AccountAddress.fromString(baseToken),
153-
baseAmount,
154-
quoteTokenVec,
155-
quoteAmount,
156-
18446744073709551615n,
157-
18446744073709551615n,
158-
salt
159-
]
160-
}
161-
})
162-
163167
try {
164-
const txn = await aptos.signAndSubmitTransaction({
165-
signer: signer,
166-
transaction: payload
167-
})
168-
const receipt = await waitForTransactionReceipt({ aptos, hash: txn.hash })
169-
return receipt
168+
let txn;
169+
if (authAccess === "key") {
170+
console.info("key-based flow")
171+
// Key-based flow using the full AptosAccount
172+
const payload = await aptos.transaction.build.simple({
173+
sender: signer.accountAddress,
174+
data: {
175+
function: `${ucs03address}::ibc_app::transfer`,
176+
typeArguments: [],
177+
functionArguments: [
178+
sourceChannelId,
179+
receiverVec,
180+
AccountAddress.fromString(baseToken),
181+
baseAmount,
182+
quoteTokenVec,
183+
quoteAmount,
184+
18446744073709551615n,
185+
18446744073709551615n,
186+
salt
187+
]
188+
}
189+
})
190+
191+
txn = await aptos.signAndSubmitTransaction({
192+
signer: signer as AptosAccount,
193+
transaction: payload
194+
});
195+
const receipt = await waitForTransactionReceipt({ aptos, hash: txn.hash });
196+
return receipt;
197+
} else {
198+
199+
const saltHex = toHex(new Uint8Array(14) );
200+
// 14 bytes + 0x 2 bytes and that walletPayload encodes it in it
201+
// so it becomes 32 byte.
202+
const walletPayload = {
203+
function: `${ucs03address}::ibc_app::transfer`,
204+
type_arguments: [],
205+
arguments: [
206+
sourceChannelId.toString(),
207+
hexToAscii(receiver), // It is hexing again in it.
208+
baseToken,
209+
baseAmount.toString(),
210+
hexToAscii(quoteToken), // It is hexing again in it.
211+
quoteAmount.toString(),
212+
18446744073709551615n.toString(),
213+
18446744073709551615n.toString(),
214+
saltHex
215+
]
216+
};
217+
try {
218+
const signedTxn = await transport.signAndSubmitTransaction({ payload: walletPayload });
219+
return ok(signedTxn.hash); // Wrap the string in a successful Result
220+
} catch (error) {
221+
return err(new Error("Transaction signing failed"));
222+
}
223+
}
170224
} catch (error) {
225+
console.info("error is:", error)
171226
return err(new Error("failed to execute aptos call", { cause: error as Error }))
172227
}
173228
}
174229
}))
175230
}
231+
function toHex(uint8array: Uint8Array): string {
232+
return "0x" + Array.from(uint8array)
233+
.map(b => b.toString(16).padStart(2, "0"))
234+
.join("");
235+
}
236+
237+
function hexToAscii(hexString: string): string {
238+
// Remove the "0x" prefix if present.
239+
if (hexString.startsWith("0x") || hexString.startsWith("0X")) {
240+
hexString = hexString.slice(2);
241+
}
242+
let ascii = "";
243+
for (let i = 0; i < hexString.length; i += 2) {
244+
ascii += String.fromCharCode(parseInt(hexString.substr(i, 2), 16));
245+
}
246+
return ascii;
247+
}

0 commit comments

Comments
 (0)
Please sign in to comment.