@owney/sdk 0.7.16-beta.5 → 0.7.16-beta.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -572,14 +572,12 @@ interface AccountAgentApy {
572
572
  weightedApyAfterFee?: number;
573
573
  weightedApyAfterFeeDetails?: AgentApyDetails;
574
574
  apyByChainAndAsset?: ApyByChainAndAsset;
575
- history?: ApyHistoryPoint[];
576
575
  }
577
576
 
578
577
  interface OwneyAccountApy {
579
578
  totalApy: string;
580
579
  agentApy: Record<AgentId, AccountAgentApy>;
581
580
  apyByChainAndAsset: ApyByChainAndAsset;
582
- history?: ApyHistoryPoint[]; // balance-weighted aggregate daily series
583
581
  }
584
582
 
585
583
  type HistoryAction = "Rebalance" | "Deposit" | "Top up" | "Withdraw" | "Earned";
@@ -0,0 +1,50 @@
1
+ // src/lib/transfer-auth.ts
2
+ import { bytesToHex } from "viem";
3
+ var ERC20_META_ABI = [
4
+ { type: "function", name: "name", stateMutability: "view", inputs: [], outputs: [{ name: "", type: "string" }] },
5
+ { type: "function", name: "version", stateMutability: "view", inputs: [], outputs: [{ name: "", type: "string" }] }
6
+ ];
7
+ function buildTransferWithAuthorizationTypedData(input) {
8
+ return {
9
+ domain: { name: input.tokenName, version: input.tokenVersion, chainId: input.chainId, verifyingContract: input.token },
10
+ types: {
11
+ TransferWithAuthorization: [
12
+ { name: "from", type: "address" },
13
+ { name: "to", type: "address" },
14
+ { name: "value", type: "uint256" },
15
+ { name: "validAfter", type: "uint256" },
16
+ { name: "validBefore", type: "uint256" },
17
+ { name: "nonce", type: "bytes32" }
18
+ ]
19
+ },
20
+ primaryType: "TransferWithAuthorization",
21
+ message: input.message
22
+ };
23
+ }
24
+ function buildReceiveWithAuthorizationTypedData(input) {
25
+ const transfer = buildTransferWithAuthorizationTypedData(input);
26
+ return {
27
+ ...transfer,
28
+ types: { ReceiveWithAuthorization: transfer.types.TransferWithAuthorization },
29
+ primaryType: "ReceiveWithAuthorization"
30
+ };
31
+ }
32
+ async function readTokenMeta(publicClient, token) {
33
+ const [tokenName, tokenVersion] = await Promise.all([
34
+ publicClient.readContract({ address: token, abi: ERC20_META_ABI, functionName: "name" }),
35
+ publicClient.readContract({ address: token, abi: ERC20_META_ABI, functionName: "version" }).catch(() => "2")
36
+ ]);
37
+ return { tokenName, tokenVersion };
38
+ }
39
+ function randomAuthNonce() {
40
+ const bytes = new Uint8Array(32);
41
+ globalThis.crypto.getRandomValues(bytes);
42
+ return bytesToHex(bytes);
43
+ }
44
+
45
+ export {
46
+ buildTransferWithAuthorizationTypedData,
47
+ buildReceiveWithAuthorizationTypedData,
48
+ readTokenMeta,
49
+ randomAuthNonce
50
+ };
@@ -0,0 +1,87 @@
1
+ // src/lib/permit2.ts
2
+ import { bytesToHex } from "viem";
3
+ var PERMIT2_ADDRESS = "0x000000000022D473030F116dDEE9F6B43aC78BA3";
4
+ var MAX_UINT256 = 2n ** 256n - 1n;
5
+ var ERC20_ALLOWANCE_ABI = [
6
+ {
7
+ type: "function",
8
+ name: "allowance",
9
+ stateMutability: "view",
10
+ inputs: [
11
+ { name: "owner", type: "address" },
12
+ { name: "spender", type: "address" }
13
+ ],
14
+ outputs: [{ name: "", type: "uint256" }]
15
+ },
16
+ {
17
+ type: "function",
18
+ name: "approve",
19
+ stateMutability: "nonpayable",
20
+ inputs: [
21
+ { name: "spender", type: "address" },
22
+ { name: "amount", type: "uint256" }
23
+ ],
24
+ outputs: [{ name: "", type: "bool" }]
25
+ },
26
+ {
27
+ type: "function",
28
+ name: "balanceOf",
29
+ stateMutability: "view",
30
+ inputs: [{ name: "account", type: "address" }],
31
+ outputs: [{ name: "", type: "uint256" }]
32
+ }
33
+ ];
34
+ function buildPermitTransferFromTypedData(input) {
35
+ return {
36
+ domain: {
37
+ name: "Permit2",
38
+ chainId: input.chainId,
39
+ verifyingContract: PERMIT2_ADDRESS
40
+ },
41
+ types: {
42
+ PermitTransferFrom: [
43
+ { name: "permitted", type: "TokenPermissions" },
44
+ { name: "spender", type: "address" },
45
+ { name: "nonce", type: "uint256" },
46
+ { name: "deadline", type: "uint256" }
47
+ ],
48
+ TokenPermissions: [
49
+ { name: "token", type: "address" },
50
+ { name: "amount", type: "uint256" }
51
+ ]
52
+ },
53
+ primaryType: "PermitTransferFrom",
54
+ message: input.message
55
+ };
56
+ }
57
+ function randomPermit2Nonce() {
58
+ const bytes = new Uint8Array(32);
59
+ globalThis.crypto.getRandomValues(bytes);
60
+ return BigInt(bytesToHex(bytes));
61
+ }
62
+ async function readPermit2Allowance(publicClient, token, owner) {
63
+ return publicClient.readContract({
64
+ address: token,
65
+ abi: ERC20_ALLOWANCE_ABI,
66
+ functionName: "allowance",
67
+ args: [owner, PERMIT2_ADDRESS]
68
+ });
69
+ }
70
+ async function readErc20Balance(publicClient, token, owner) {
71
+ return publicClient.readContract({
72
+ address: token,
73
+ abi: ERC20_ALLOWANCE_ABI,
74
+ functionName: "balanceOf",
75
+ args: [owner]
76
+ });
77
+ }
78
+
79
+ export {
80
+ PERMIT2_ADDRESS,
81
+ MAX_UINT256,
82
+ ERC20_ALLOWANCE_ABI,
83
+ buildPermitTransferFromTypedData,
84
+ randomPermit2Nonce,
85
+ readPermit2Allowance,
86
+ readErc20Balance
87
+ };
@@ -0,0 +1,55 @@
1
+ // src/errors.ts
2
+ var OwneyError = class extends Error {
3
+ code;
4
+ details;
5
+ agentId;
6
+ constructor(code, message, details, agentId) {
7
+ const prefix = agentId ? `[${code}][agent:${agentId}]` : `[${code}]`;
8
+ super(`${prefix} ${message}`);
9
+ this.name = "OwneyError";
10
+ this.code = code;
11
+ this.details = details;
12
+ this.agentId = agentId;
13
+ }
14
+ };
15
+ var AgentNotFoundError = class extends OwneyError {
16
+ constructor(agentId, available) {
17
+ super(
18
+ "AGENT_NOT_FOUND",
19
+ `Unknown agent "${agentId}". Available agents: ${available.join(", ")}`,
20
+ { agentId, available },
21
+ agentId
22
+ );
23
+ this.name = "AgentNotFoundError";
24
+ }
25
+ };
26
+ var NotConnectedError = class extends OwneyError {
27
+ constructor() {
28
+ super("NOT_CONNECTED", "Not connected. Call sdk.connect(provider) first.");
29
+ this.name = "NotConnectedError";
30
+ }
31
+ };
32
+ var AgentChainIncompatibleError = class extends OwneyError {
33
+ incompatibleAgents;
34
+ connectedChainId;
35
+ constructor(incompatibleAgents, connectedChainId) {
36
+ const details = incompatibleAgents.map(
37
+ ({ agentId, supportedChainIds }) => `"${agentId}" supports chains [${supportedChainIds.join(", ")}]`
38
+ ).join("; ");
39
+ super(
40
+ "AGENT_CHAIN_INCOMPATIBLE",
41
+ `Chain ${connectedChainId} is not supported by the following agents: ${details}`,
42
+ { incompatibleAgents, connectedChainId }
43
+ );
44
+ this.name = "AgentChainIncompatibleError";
45
+ this.incompatibleAgents = incompatibleAgents;
46
+ this.connectedChainId = connectedChainId;
47
+ }
48
+ };
49
+
50
+ export {
51
+ OwneyError,
52
+ AgentNotFoundError,
53
+ NotConnectedError,
54
+ AgentChainIncompatibleError
55
+ };
@@ -0,0 +1,92 @@
1
+ import {
2
+ OwneyError
3
+ } from "./chunk-GMNQBWUB.js";
4
+
5
+ // src/lib/debug.ts
6
+ var configuredDebug = false;
7
+ function setOwneyDebug(enabled) {
8
+ configuredDebug = enabled;
9
+ }
10
+ function isOwneyDebug() {
11
+ return globalThis.__OWNEY_DEBUG__ === true || configuredDebug;
12
+ }
13
+ function debugLog(scope, message, data) {
14
+ if (!isOwneyDebug()) return;
15
+ if (data === void 0) {
16
+ console.log(`[${scope}] ${message}`);
17
+ } else {
18
+ console.log(`[${scope}] ${message}`, data);
19
+ }
20
+ }
21
+
22
+ // src/lib/routing-api.ts
23
+ var ROUTING_API_BASE_URL = "https://owney-routing-api-243946518160.europe-west4.run.app";
24
+ async function fetchOrgAgentConfig(apiKey, baseUrl = ROUTING_API_BASE_URL) {
25
+ const url = `${baseUrl}/api/v1/agent/org-config`;
26
+ try {
27
+ const res = await fetch(url, {
28
+ method: "GET",
29
+ headers: {
30
+ "Content-Type": "application/json",
31
+ "x-owney-api-key": `${apiKey}`
32
+ }
33
+ });
34
+ if (!res.ok) {
35
+ if (res.status !== 404) {
36
+ console.warn(
37
+ `[owney-sdk] Could not read org agent config (${res.status}); leaving user profiles unchanged.`
38
+ );
39
+ }
40
+ return null;
41
+ }
42
+ const json = await res.json();
43
+ const policy = json.success ? json.data ?? null : null;
44
+ debugLog(
45
+ "owney-sdk",
46
+ policy ? "org agent config: loaded" : "org agent config: none set by this partner \u2014 user profiles will be left as they are",
47
+ policy ?? void 0
48
+ );
49
+ return policy;
50
+ } catch (error) {
51
+ console.warn(
52
+ "[owney-sdk] Could not read org agent config (non-fatal):",
53
+ error instanceof Error ? error.message : String(error)
54
+ );
55
+ return null;
56
+ }
57
+ }
58
+ async function fetchAgentKeys(apiKey, baseUrl = ROUTING_API_BASE_URL) {
59
+ const url = `${baseUrl}/api/v1/agent/keys`;
60
+ const res = await fetch(url, {
61
+ method: "GET",
62
+ headers: {
63
+ "Content-Type": "application/json",
64
+ "x-owney-api-key": `${apiKey}`
65
+ }
66
+ });
67
+ if (!res.ok) {
68
+ const text = await res.text().catch(() => "");
69
+ throw new OwneyError(
70
+ "API_ROUTING_ERROR",
71
+ `Routing API error ${res.status}: ${text}`,
72
+ { statusCode: res.status, responseBody: text }
73
+ );
74
+ }
75
+ const json = await res.json();
76
+ if (!json.success) {
77
+ throw new OwneyError(
78
+ "API_ROUTING_FAILED",
79
+ `Routing API request failed: ${json.message}`,
80
+ { message: json.message }
81
+ );
82
+ }
83
+ return json.data;
84
+ }
85
+
86
+ export {
87
+ setOwneyDebug,
88
+ debugLog,
89
+ ROUTING_API_BASE_URL,
90
+ fetchOrgAgentConfig,
91
+ fetchAgentKeys
92
+ };
@@ -0,0 +1,222 @@
1
+ import {
2
+ buildReceiveWithAuthorizationTypedData,
3
+ randomAuthNonce
4
+ } from "./chunk-5LU2SHO7.js";
5
+ import {
6
+ SURFLIQUID_CHAIN_ID,
7
+ SURFLIQUID_USDC_ADDRESS
8
+ } from "./chunk-VHQ4VXY7.js";
9
+
10
+ // src/agents/surfliquid/surfliquid.calls.ts
11
+ import { encodeFunctionData } from "viem";
12
+
13
+ // src/agents/surfliquid/surfliquid.contracts.ts
14
+ import { parseAbi } from "viem";
15
+ var SURFLIQUID_FACTORY_ADDRESS = "0x8fa50DeA8DB10987D7d22ac092001c3613C18779";
16
+ var SURFLIQUID_FACTORY_ABI = parseAbi([
17
+ "function deployVault(address vaultOwner, bytes32 salt) returns (address)",
18
+ "function computeVaultAddress(address vaultOwner, bytes32 salt) view returns (address)"
19
+ ]);
20
+ var SURFLIQUID_VAULT_ABI = parseAbi([
21
+ "function initialDeposit(address asset, address vault, uint256 amount)",
22
+ "function userDeposit(address asset, uint256 amount)",
23
+ // amount 0 withdraws everything; proceeds go to the vault's owner.
24
+ "function withdraw(address asset, uint256 amount)",
25
+ "function assetHasInitialDeposit(address asset) view returns (bool)",
26
+ "function owner() view returns (address)"
27
+ ]);
28
+ var USDC_ABI = parseAbi([
29
+ "function approve(address spender, uint256 amount)",
30
+ "function transfer(address to, uint256 amount)",
31
+ "function balanceOf(address account) view returns (uint256)",
32
+ "function receiveWithAuthorization(address from, address to, uint256 value, uint256 validAfter, uint256 validBefore, bytes32 nonce, bytes signature)"
33
+ ]);
34
+
35
+ // src/agents/surfliquid/surfliquid.calls.ts
36
+ var call = (to, abi, functionName, args) => ({
37
+ to,
38
+ data: encodeFunctionData({ abi, functionName, args })
39
+ });
40
+ function buildDepositCalls(input) {
41
+ const { smartAccount, vault, amount, authorization, deploySalt } = input;
42
+ if (authorization.to.toLowerCase() !== smartAccount.toLowerCase()) {
43
+ throw new Error("Transfer authorization must pay the smart account");
44
+ }
45
+ if (authorization.value < amount) {
46
+ throw new Error("Transfer authorization is worth less than the deposit");
47
+ }
48
+ if (!input.hasInitialDeposit && !input.morphoVault) {
49
+ throw new Error("A first deposit needs a target morpho vault");
50
+ }
51
+ const calls = [];
52
+ if (deploySalt) {
53
+ calls.push(
54
+ call(SURFLIQUID_FACTORY_ADDRESS, SURFLIQUID_FACTORY_ABI, "deployVault", [
55
+ smartAccount,
56
+ deploySalt
57
+ ])
58
+ );
59
+ }
60
+ calls.push(
61
+ call(SURFLIQUID_USDC_ADDRESS, USDC_ABI, "receiveWithAuthorization", [
62
+ authorization.from,
63
+ authorization.to,
64
+ authorization.value,
65
+ authorization.validAfter,
66
+ authorization.validBefore,
67
+ authorization.nonce,
68
+ authorization.signature
69
+ ]),
70
+ call(SURFLIQUID_USDC_ADDRESS, USDC_ABI, "approve", [vault, amount]),
71
+ input.hasInitialDeposit ? call(vault, SURFLIQUID_VAULT_ABI, "userDeposit", [SURFLIQUID_USDC_ADDRESS, amount]) : call(vault, SURFLIQUID_VAULT_ABI, "initialDeposit", [
72
+ SURFLIQUID_USDC_ADDRESS,
73
+ input.morphoVault,
74
+ amount
75
+ ])
76
+ );
77
+ return calls;
78
+ }
79
+ function buildWithdrawCalls(input) {
80
+ return [
81
+ call(input.vault, SURFLIQUID_VAULT_ABI, "withdraw", [
82
+ SURFLIQUID_USDC_ADDRESS,
83
+ input.amount ?? 0n
84
+ ])
85
+ ];
86
+ }
87
+ function buildSweepCalls(input) {
88
+ return [call(SURFLIQUID_USDC_ADDRESS, USDC_ABI, "transfer", [input.owner, input.amount])];
89
+ }
90
+
91
+ // src/agents/surfliquid/surfliquid.sponsorship.ts
92
+ var AUTHORIZATION_TTL_SECONDS = 3600n;
93
+ var SubmittedError = class extends Error {
94
+ constructor(message, userOpHash) {
95
+ super(message);
96
+ this.userOpHash = userOpHash;
97
+ this.name = "SubmittedError";
98
+ }
99
+ userOpHash;
100
+ };
101
+ var isSafeToRetry = (error) => !(error instanceof SubmittedError);
102
+ async function resolveVault(ctx) {
103
+ const registered = await ctx.api.getVault(ctx.wallet.ownerAddress);
104
+ const smartAccount = ctx.wallet.smartAccountAddress;
105
+ if (!registered.userVaultAddress) {
106
+ const salt2 = registered.deploymentSalt ?? (await ctx.api.prepare(SURFLIQUID_CHAIN_ID)).salt;
107
+ return {
108
+ vault: await ctx.chain.computeVaultAddress(smartAccount, salt2),
109
+ deploySalt: salt2,
110
+ registerAfterDeposit: true
111
+ };
112
+ }
113
+ const vault = registered.userVaultAddress;
114
+ if (await ctx.chain.isDeployed(vault)) {
115
+ const owner = await ctx.chain.readVaultOwner(vault);
116
+ if (owner.toLowerCase() !== smartAccount.toLowerCase()) {
117
+ throw new Error(`SurfLiquid vault ${vault} is not owned by the smart account`);
118
+ }
119
+ return { vault, registerAfterDeposit: false };
120
+ }
121
+ const salt = registered.deploymentSalt;
122
+ const deployable = salt ? await ctx.chain.computeVaultAddress(smartAccount, salt) : void 0;
123
+ if (!salt || deployable?.toLowerCase() !== vault.toLowerCase()) {
124
+ throw new Error(`Registered SurfLiquid vault ${vault} does not match this smart account`);
125
+ }
126
+ return { vault, deploySalt: salt, registerAfterDeposit: false };
127
+ }
128
+ async function pickMorphoVault(api) {
129
+ const candidates = await api.getBestVault("USDC");
130
+ const candidate = candidates.find((option) => option.chainId === SURFLIQUID_CHAIN_ID);
131
+ if (!candidate) {
132
+ throw new Error(`SurfLiquid has no morpho vault for USDC on chain ${SURFLIQUID_CHAIN_ID}`);
133
+ }
134
+ return candidate.vaultAddress;
135
+ }
136
+ async function depositSponsored(input) {
137
+ const { api, chain, wallet, amount } = input;
138
+ const { vault, deploySalt, registerAfterDeposit } = await resolveVault(input);
139
+ const hasInitialDeposit = deploySalt ? false : await chain.hasInitialDeposit(vault, SURFLIQUID_USDC_ADDRESS);
140
+ const morphoVault = hasInitialDeposit ? void 0 : await pickMorphoVault(api);
141
+ const { tokenName, tokenVersion } = await chain.readTokenMeta();
142
+ const message = {
143
+ from: wallet.ownerAddress,
144
+ to: wallet.smartAccountAddress,
145
+ value: amount,
146
+ validAfter: 0n,
147
+ validBefore: BigInt(Math.floor(Date.now() / 1e3)) + AUTHORIZATION_TTL_SECONDS,
148
+ nonce: randomAuthNonce()
149
+ };
150
+ const signature = await wallet.signTransferAuthorization(
151
+ buildReceiveWithAuthorizationTypedData({
152
+ token: SURFLIQUID_USDC_ADDRESS,
153
+ chainId: SURFLIQUID_CHAIN_ID,
154
+ tokenName,
155
+ tokenVersion,
156
+ message
157
+ })
158
+ );
159
+ const txHash = await wallet.sendCalls(
160
+ buildDepositCalls({
161
+ smartAccount: wallet.smartAccountAddress,
162
+ vault,
163
+ amount,
164
+ authorization: { ...message, signature },
165
+ hasInitialDeposit,
166
+ morphoVault,
167
+ deploySalt
168
+ })
169
+ );
170
+ if (registerAfterDeposit && deploySalt) {
171
+ try {
172
+ await api.confirm({
173
+ userVaultAddress: vault,
174
+ homeChainId: SURFLIQUID_CHAIN_ID,
175
+ deploymentSalt: deploySalt,
176
+ initialAssets: []
177
+ });
178
+ } catch (error) {
179
+ console.warn(
180
+ "[owney-sdk] SurfLiquid vault registration failed after a successful deposit:",
181
+ error instanceof Error ? error.message : String(error)
182
+ );
183
+ }
184
+ }
185
+ return { txHash, vault };
186
+ }
187
+ async function withdrawSponsored(input) {
188
+ const { api, chain, wallet, amount } = input;
189
+ const registered = await api.getVault(wallet.ownerAddress);
190
+ if (!registered.userVaultAddress) {
191
+ throw new Error("SurfLiquid has no vault registered for this wallet");
192
+ }
193
+ const vault = registered.userVaultAddress;
194
+ const owner = await chain.readVaultOwner(vault);
195
+ if (owner.toLowerCase() !== wallet.smartAccountAddress.toLowerCase()) {
196
+ throw new Error(`SurfLiquid vault ${vault} is not owned by the smart account`);
197
+ }
198
+ const withdrawHash = await wallet.sendCalls(buildWithdrawCalls({ vault, amount }));
199
+ try {
200
+ const proceeds = await chain.usdcBalanceOf(wallet.smartAccountAddress);
201
+ if (proceeds === 0n) return { txHash: withdrawHash, amount: "0" };
202
+ const sweepHash = await wallet.sendCalls(
203
+ buildSweepCalls({ owner: wallet.ownerAddress, amount: proceeds })
204
+ );
205
+ return { txHash: sweepHash, amount: proceeds.toString() };
206
+ } catch (error) {
207
+ throw new SubmittedError(
208
+ `SurfLiquid withdrawal ${withdrawHash} landed but the sweep did not: ${error instanceof Error ? error.message : String(error)}`
209
+ );
210
+ }
211
+ }
212
+
213
+ export {
214
+ SURFLIQUID_FACTORY_ADDRESS,
215
+ SURFLIQUID_FACTORY_ABI,
216
+ SURFLIQUID_VAULT_ABI,
217
+ USDC_ABI,
218
+ SubmittedError,
219
+ isSafeToRetry,
220
+ depositSponsored,
221
+ withdrawSponsored
222
+ };
@@ -0,0 +1,39 @@
1
+ // src/agents/surfliquid/surfliquid.constants.ts
2
+ var SURFLIQUID_CHAIN_ID = 8453;
3
+ var SURFLIQUID_CHAIN_NAME = "BASE";
4
+ var SURFLIQUID_USDC_ADDRESS = "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913";
5
+ var SURFLIQUID_USDC_DECIMALS = 6;
6
+ var SURFLIQUID_MIN_DEPOSIT = "0";
7
+ var SURFLIQUID_APPROVAL_TARGET = 100000000000n;
8
+ var SURFLIQUID_SUPPORTED_ASSETS = [
9
+ {
10
+ chainId: SURFLIQUID_CHAIN_ID,
11
+ chain: SURFLIQUID_CHAIN_NAME,
12
+ assets: [{ symbol: "USDC", minDepositAmount: SURFLIQUID_MIN_DEPOSIT }]
13
+ }
14
+ ];
15
+ var SURFLIQUID_ACTION_MAP = {
16
+ // INITIAL_DEPOSIT is the user's real first deposit, so surface it like any
17
+ // other funding ("Top up"). The mini-app intentionally hides the "Deposit"
18
+ // action (it marks Zyfai's smart-account-creation event), which would
19
+ // otherwise drop a SurfLiquid user's only history row.
20
+ INITIAL_DEPOSIT: "Top up",
21
+ DEPOSIT: "Top up",
22
+ USER_DEPOSIT: "Top up",
23
+ WITHDRAWAL: "Withdraw",
24
+ USER_WITHDRAWAL: "Withdraw",
25
+ REBALANCE: "Rebalance",
26
+ REBALANCE_COMPLETED: "Rebalance",
27
+ CROSS_CHAIN_REBALANCE: "Rebalance",
28
+ MERKL_CLAIM: "Earned"
29
+ };
30
+
31
+ export {
32
+ SURFLIQUID_CHAIN_ID,
33
+ SURFLIQUID_CHAIN_NAME,
34
+ SURFLIQUID_USDC_ADDRESS,
35
+ SURFLIQUID_USDC_DECIMALS,
36
+ SURFLIQUID_APPROVAL_TARGET,
37
+ SURFLIQUID_SUPPORTED_ASSETS,
38
+ SURFLIQUID_ACTION_MAP
39
+ };