Skip to content

Commit

Permalink
feat: initialized evm provider and sui payloads (#25)
Browse files Browse the repository at this point in the history
  • Loading branch information
R0bi7 authored Nov 25, 2024
1 parent e4dd9ca commit b2d8522
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 35 deletions.
29 changes: 24 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,9 @@ SDK abstracts away the wallet and public RPC clients using `ChainProviderType` T
- `EvmProvider`: Provider used for EVM type chains (ETH, BSC, etc..). Implemented using [viem](https://viem.sh/docs/clients/wallet#json-rpc-accounts).
- `SuiProvider`: Provider used for SUI type chains (SUI). Implemented using [@mysten/sui](https://github.com/MystenLabs/sui) and [@mysten/wallet-standard](https://docs.sui.io/standards/wallet-standard).

Optionally, you can supply EVM providers (wallet and public clients) yourself (see `EvmInitializedConfig`).
SUI accepts only initialized Wallet, Account and Client.

Providers are used to request wallet actions (prompts wallet extension) and make RPC calls to the RPC nodes.

EVM Provider example:
Expand All @@ -111,7 +114,11 @@ EVM Provider example:
import { EvmProvider } from "@balanced/solver-sdk"

// NOTE: user address should be provided by application when user connects wallet
const evmProvider = new EvmProvider("0x3FF796F1968C515f6AC2833545B5Dd2cE765A1a1", "arb", (window as any).ethereum)
const evmProvider = new EvmProvider({
userAddress: "0x601020c5797Cdd34f64476b9bf887a353150Cb9a",
chain: "arb",
provider: (window as any).ethereum,
})
```

SUI Provider example (uses [SUI dApp Kit](https://sdk.mystenlabs.com/dapp-kit/):
Expand All @@ -125,7 +132,7 @@ const { currentWallet, connectionStatus } = useCurrentWallet()

// check that wallet is connected and account is defined
if (connectionStatus === "connected" && account) {
const suiProvider = new SuiProvider(currentWallet, account, "mainnet")
const suiProvider = new SuiProvider({ wallet, account, client })
} else {
throw new Error("Wallet or Account undefined. Please connect wallet and select account.")
}
Expand All @@ -142,7 +149,11 @@ import { IntentService, EvmProvider, CreateIntentOrderPayload, IntentStatusCode

// create EVM provider because "arb" is of ChainType "evm" (defined in ChainConfig type - see section Load SDK Config)
// NOTE: window can only be accessed client side (browser)
const evmProvider = new EvmProvider("0x601020c5797Cdd34f64476b9bf887a353150Cb9a", "arb", (window as any).ethereum)
const evmProvider = new EvmProvider({
userAddress: "0x601020c5797Cdd34f64476b9bf887a353150Cb9a",
chain: "arb",
provider: (window as any).ethereum,
})

const intentOrderPayload: CreateIntentOrderPayload = {
quote_uuid: "a0dd7652-b360-4123-ab2d-78cfbcd20c6b",
Expand Down Expand Up @@ -221,7 +232,11 @@ Example cancel order:
```typescript
import { IntentService, SwapOrder, EvmProvider } from "@balanced/solver-sdk"

const evmProvider = new EvmProvider("0x601020c5797Cdd34f64476b9bf887a353150Cb9a", "arb", (window as any).ethereum)
const evmProvider = new EvmProvider({
userAddress: "0x601020c5797Cdd34f64476b9bf887a353150Cb9a",
chain: "arb",
provider: (window as any).ethereum
})
const intentOrder: Result<SwapOrder> = await IntentService.getOrder(
"0xabcdefasdasdsafssadasdsadsadasdsadasdsadsa",
IntentService.getChainConfig("arb").intentContract,
Expand Down Expand Up @@ -259,7 +274,11 @@ Example get order:
```typescript
import { IntentService, SwapOrder, EvmProvider } from "@balanced/solver-sdk"

const evmProvider = new EvmProvider("0x601020c5797Cdd34f64476b9bf887a353150Cb9a", "arb", (window as any).ethereum)
const evmProvider = new EvmProvider({
userAddress: "0x601020c5797Cdd34f64476b9bf887a353150Cb9a",
chain: "arb",
provider: (window as any).ethereum,
})
const intentOrder: Result<SwapOrder> = await IntentService.getOrder(
"0xabcdefasdasdsafssadasdsadsadasdsadasdsadsa",
IntentService.getChainConfig("arb").intentContract,
Expand Down
59 changes: 41 additions & 18 deletions src/entities/Providers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,40 +10,63 @@ import {
type WalletClient,
} from "viem"
import { type Wallet, type WalletAccount } from "@mysten/wallet-standard"
import { getFullnodeUrl, SuiClient } from "@mysten/sui/client"
import type { ChainName, ChainType, SuiNetworkType } from "../types.js"
import { SuiClient } from "@mysten/sui/client"
import type { ChainName, ChainType } from "../types.js"
import { getEvmViemChain } from "../constants.js"
import { isEvmInitializedConfig, isEvmUninitializedConfig } from "../guards.js"

export type CustomProvider = { request(...args: any): Promise<any> }

export type EvmUninitializedConfig = {
userAddress: Address
chain: ChainName
provider: CustomProvider
}

export type EvmInitializedConfig = {
walletClient: WalletClient<CustomTransport, Chain, Account>
publicClient: PublicClient<CustomTransport>
}

export class EvmProvider {
public readonly walletClient: WalletClient<CustomTransport, Chain, Account>
public readonly publicClient: PublicClient<CustomTransport>

constructor(userAddress: Address, chain: ChainName, provider: CustomProvider) {
this.walletClient = createWalletClient({
account: userAddress,
transport: custom(provider),
chain: getEvmViemChain(chain),
})
this.publicClient = createPublicClient({
transport: custom(provider),
chain: getEvmViemChain(chain),
})

console.log("Evm provider initialised with chain id:", this.walletClient.chain.id)
constructor(payload: EvmUninitializedConfig | EvmInitializedConfig) {
if (isEvmUninitializedConfig(payload)) {
this.walletClient = createWalletClient({
account: payload.userAddress,
transport: custom(payload.provider),
chain: getEvmViemChain(payload.chain),
})
this.publicClient = createPublicClient({
transport: custom(payload.provider),
chain: getEvmViemChain(payload.chain),
})
} else if (isEvmInitializedConfig(payload)) {
this.walletClient = payload.walletClient
this.publicClient = payload.publicClient
} else {
throw new Error("Invalid configuration payload passed to EvmProvider")
}
}
}

export type SuiInitializedConfig = {
wallet: Wallet
account: WalletAccount
client: SuiClient
}

export class SuiProvider {
public readonly wallet: Wallet
public readonly account: WalletAccount
public readonly client: SuiClient

constructor(wallet: Wallet, account: WalletAccount, net: SuiNetworkType) {
this.wallet = wallet
this.account = account
this.client = new SuiClient({ url: getFullnodeUrl(net) })
constructor(payload: SuiInitializedConfig) {
this.wallet = payload.wallet
this.account = payload.account
this.client = payload.client
}
}

Expand Down
13 changes: 13 additions & 0 deletions src/guards.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type { ChainConfig, EvmChainConfig, SuiChainConfig } from "./types.js"
import type { EvmInitializedConfig, EvmUninitializedConfig } from "./entities/index.js"

export function isEvmChainConfig(value: ChainConfig): value is EvmChainConfig {
return typeof value === "object" && value.chain.type == "evm"
Expand All @@ -7,3 +8,15 @@ export function isEvmChainConfig(value: ChainConfig): value is EvmChainConfig {
export function isSuiChainConfig(value: ChainConfig): value is SuiChainConfig {
return typeof value === "object" && value.chain.type == "sui"
}

export function isEvmUninitializedConfig(
value: EvmUninitializedConfig | EvmInitializedConfig,
): value is EvmUninitializedConfig {
return typeof value === "object" && "userAddress" in value && "chain" in value
}

export function isEvmInitializedConfig(
value: EvmUninitializedConfig | EvmInitializedConfig,
): value is EvmInitializedConfig {
return typeof value === "object" && "walletClient" in value && "publicClient" in value
}
12 changes: 0 additions & 12 deletions src/services/SuiIntentService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,6 @@ export class SuiIntentService {
toChainConfig: ChainConfig,
provider: SuiProvider,
): Promise<Result<string>> {
console.log("[SuiIntentService.createIntentOrder] payload", payload)

try {
const intent = new SwapOrder(
0n,
Expand All @@ -43,12 +41,9 @@ export class SuiIntentService {

const tx = new Transaction()

console.log("[SuiIntentService.createIntentOrder] isNative", isNative)

let coin: any = isNative
? await SuiIntentService.getNativeCoin(tx, intent)
: await SuiIntentService.getCoin(tx, intent.token, intent.amount.valueOf(), provider.account.address, provider)
console.log("[SuiIntentService.createIntentOrder] coin", coin)

tx.moveCall({
target: `${fromChainConfig.packageId}::main::swap`,
Expand All @@ -64,11 +59,8 @@ export class SuiIntentService {
typeArguments: [intent.token],
})

console.log("[SuiIntentService.createIntentOrder] tx after moveCall", tx)

const signerAccount = provider.account
const chain = signerAccount.chains[0]
console.log("[SuiIntentService.signerAccount] tx after moveCall", tx)

if (!chain) {
return {
Expand All @@ -77,8 +69,6 @@ export class SuiIntentService {
}
}

console.log("[SuiIntentService.signerAccount] chain", chain)

const { bytes, signature } = await signTransaction(provider.wallet, {
transaction: tx,
account: provider.account,
Expand All @@ -93,8 +83,6 @@ export class SuiIntentService {
},
})

console.log("[SuiIntentService.signerAccount] signAndExecuteTransaction result", result)

return {
ok: true,
value: result.digest,
Expand Down

0 comments on commit b2d8522

Please sign in to comment.