| name | liquidium-sdk-integration |
| description | Use this skill first for the Liquidium TypeScript SDK authless instant-loan flow, `@liquidium/client`, `LiquidiumClient`, `client.instantLoans`, wallet adapters, Liquidium profile creation, market data, quotes, borrowing, supply flows, positions, activities, or history. Use it whenever the user wants to integrate Liquidium into a TypeScript, React, or Vite app, or asks how to call Liquidium SDK methods correctly. |
| license | MIT |
| metadata | {"title":"Liquidium SDK Integration","category":"TypeScript SDK"} |
Liquidium SDK Integration
@liquidium/client reads Liquidium market and position data, then executes authless instant loans and advanced profile-based lending flows.
Priority: authless instant loans are the default product flow. Use client.instantLoans first, deposit-address profile flows second, and ETH contract interaction only when explicitly needed.
Default Decision
When the user asks for a simple borrow, loan, collateral deposit, repayment target, or Liquidium integration and does not explicitly ask to manage Liquidium profiles, implement the authless instant-loan flow with client.instantLoans.
Do not require the user to create a Liquidium profile, sign a borrow message, or call client.lending.borrow(...) for the default flow. The SDK creates the backing lending profile and returns generated deposit and repayment targets.
Use profile-based client.accounts and client.lending only when the user explicitly asks for advanced profile management, existing profile positions, manual supply/repay tracking, signed borrow/withdraw flows, or lower-level wallet orchestration.
Modules
import { LiquidiumClient } from "@liquidium/client";
const client = new LiquidiumClient({});
The client exposes: instantLoans, accounts, lending, positions, market, activities, history, quote.
Setup
Install the client package:
npm install @liquidium/client
pnpm add @liquidium/client
bun add @liquidium/client
Use the SDK in browser apps and modern TypeScript runtimes. Browser integrations
need fetch, BigInt, and standard ESM support. Follow the host app's package
manager and build tooling.
Minimal config:
const client = new LiquidiumClient({});
Richer config when the flow requires it:
const client = new LiquidiumClient({
environment: "mainnet",
apiBaseUrl: "https://your-app.example.com/api/sdk",
headers: { "x-client-name": "my-app" },
evmRpcUrl: "https://mainnet.infura.io/v3/<key>",
timeoutMs: 30_000,
});
Config requirements:
environment: sets the canister preset. Only mainnet is bundled; pass canisterIds explicitly for custom deployments
apiBaseUrl: overrides the default Liquidium service root for history, activities, inflow reporting, instantLoans.create(...), and instantLoans.findByAddress(...). It is not needed for instantLoans.get(...), borrow(...), withdraw(...), or default ETH stablecoin deposit-address supply/repay targets
headers: adds headers to Liquidium SDK HTTP API requests, for example app attribution or auth from a backend proxy
fetch: supplies a custom fetch implementation when the runtime needs one
evmRpcUrl / evmPublicClient: required for lower-level ETH contract-interaction supply planning and allowance polling. Use evmRpcHeaders when the RPC provider authenticates with HTTP headers
identity / icHost: custom ICP agent configuration
canisterIds.instantLoans: defaults to mainnet u5rm3-niaaa-aaaar-qb7eq-cai; override it for custom deployments
Missing required service configuration is a client configuration problem.
Affected methods throw LiquidiumErrorCode.VALIDATION_ERROR, not
SERVICE_UNAVAILABLE.
For Vite example apps, expose the RPC URL through a VITE_ variable. If using
Infura, prefer VITE_INFURA_API_KEY and derive the URL in app config:
const evmRpcUrl = import.meta.env.VITE_INFURA_API_KEY
? `https://mainnet.infura.io/v3/${import.meta.env.VITE_INFURA_API_KEY}`
: import.meta.env.VITE_EVM_RPC_URL;
Vite env vars are bundled client-side. Treat Infura browser keys as publishable
or route RPC calls through a server if the key must remain private.
Module Guide
instantLoans
Authless instant loans. This is the default simple borrow UX: create a loan,
show the generated collateral deposit address, restore by reference, and show
the actionable repayment amount when the user wants to close the loan.
client.instantLoans.create(...);
client.instantLoans.get({ ref });
client.instantLoans.get({ loanId });
client.instantLoans.findByAddress(address);
client.quote.calculateLtv(...);
create(...) accepts direct collateralAmount, borrowAmount, ltvMaxBps, and
depositWindowSeconds values in base units, plus external borrow/refund
destinations. It validates positive amounts, loads pools and prices, applies
SDK-side instant-loan LTV guards, creates the loan, then returns the hydrated
loan.
Current LTV guards require ltvMaxBps to be at least the current implied LTV
plus the SDK slippage buffer and no higher than the collateral pool max LTV. Do
not confuse the quote module's targetLtvBps with create(...)'s ltvMaxBps. Use
client.quote.calculateLtv(...) when clients need to preview the current LTV
from chosen borrow and collateral amounts before calling create(...).
create(...) and get(...) do not require a wallet adapter, profile ID, or
message signing. The SDK returns deposit and repay targets for the generated
profileId; get(...) also returns position plus repayment.amount for the
full amount to send to the repayment target, including inflow fee and interest
buffer.
Deposit and repayment targets are distinct generated inflow targets. Show
loan.depositTarget only when asking the user to send collateral. Show
loan.repayment.target or loan.repayTarget only when asking the user to repay
debt. Do not assume these addresses/accounts match, do not reuse the collateral
deposit target for repayment, and do not cache one target for both phases.
Reload with client.instantLoans.get({ ref }) before displaying repayment
instructions so the app uses the canonical repayment amount and target.
findByAddress(...) is a recovery helper and returns candidates only. Follow it
with get({ loanId }) or get({ ref }) before showing canonical loan state.
market
Pool discovery, asset prices, and per-reserve data.
client.market.listPools();
client.market.findPool({ asset, chain });
client.market.getReserveData({ asset, chain });
client.market.getAssetPrices();
client.market.getPoolRate(poolId);
Pool includes decimals, availableLiquidity, caps, rates, and index data.
quote
Quote-first planning. Use this to calculate borrow USD value, required
collateral, current LTV, validation errors, and warnings from caller-supplied market data.
For default authless loans, the quote can help choose collateralAmount and
borrowAmount; execution still goes through client.instantLoans.create(...).
For advanced profile-based borrowing, fetch pools and prices first, then call
quote before preparing the signed borrow.
const pools = await client.market.listPools();
const prices = await client.market.getAssetPrices();
const quote = client.quote.getQuote(request, pools, prices);
const ltv = client.quote.calculateLtv(ltvRequest, pools, prices);
getQuote(...) is synchronous and pure after the app has already fetched pools
and prices. It returns validationErrors and warnings; it does not throw for
normal quote validation failures such as missing pools, missing prices, invalid
LTV, too-small borrow amounts, or disallowed same-asset borrowing. Treat a quote
with validation errors as non-executable.
calculateLtv(...) is also synchronous and pure after fetching pools and prices.
It accepts borrowAmount, borrowPoolId, collateralAmount, and
collateralPoolId, then returns ltvBps, borrowUsd, collateralUsd,
maxAllowedLtvBps, asset metadata, and validationErrors.
accounts
Profile creation and resolution.
client.accounts.prepareCreateProfile(...);
client.accounts.createProfile(...);
client.accounts.getProfileId(walletAddress);
client.accounts.listLinkedWallets(profileId);
lending
Advanced profile-based borrow, withdraw, supply, repay, inflow reporting, and supply tracking. Do not use this as the default borrow UX; most apps should start with client.instantLoans.
client.lending.prepareBorrow(...);
client.lending.prepareWithdraw(...);
client.lending.borrow(...);
client.lending.withdraw(...);
client.lending.supply(...);
client.lending.estimateInflowFee({ asset: "USDT", chain: "ETH" });
client.lending.submitInflow({ txid, chain: "BTC", type: "DEPOSIT" });
positions
Existing profile state plus aggregate position reads.
client.positions.getPosition(profileId, poolId);
client.positions.listPositions(profileId);
client.positions.getHealthFactor(profileId);
client.positions.getUserStats(profileId);
client.positions.getUserPositionSummary(profileId);
client.positions.getUserReserves(profileId);
client.positions.getMaxRepayAmount(profileId, poolId, bufferBps?);
activities
Receipt status and active/completed/all activity lists. Requires apiBaseUrl.
client.activities.list({ profileId, filter: "all" });
client.activities.getStatus({ profileId, id });
history
User or pool history. Requires apiBaseUrl.
client.history.getUserTransactionHistory(profileId, filters?);
client.history.getLiquidationHistory(profileId, filters?);
client.history.getPoolHistory(poolId, window?);
client.history.getPoolConfigHistory(poolId, cursor?);
client.history.getBorrowRateHistory(poolId, window?);
User history entries expose txids?: string[]; do not expect separate inbound
or outbound txid fields. Pool history entries are rate/utilization samples.
Pool config history entries are reserve configuration-change snapshots
(type: "configuration_change") with pool config, caps, indexes, liquidity,
debt, and sameAssetBorrowing fields.
Rate and Amount Formatting
Amount fields are bigint base units. Format them with the asset or pool
decimals; do not display raw base-unit values as user amounts.
Rate and risk-ratio fields such as lendingRate, borrowingRate,
utilizationRate, maxLtv, liquidationThreshold, pool-history rates, and
reserve-history rates are fixed-point values scaled by rateDecimals, usually
27. Do not render raw scaled values as percentages.
Never convert a raw scaled rate directly to display text or append % to it.
That can produce impossible UI values such as 3.7e+24%. Divide by
10 ** rateDecimals first, then multiply by 100 only for percentage display,
and format the final value with fixed decimals or Intl.NumberFormat.
function formatScaledRatePercent(
scaledRate: bigint,
rateDecimals: bigint,
fractionDigits = 2,
): string {
const scale = 10n ** rateDecimals;
const percentScale = 100n;
const displayScale = 10n ** BigInt(fractionDigits);
const rounded =
(scaledRate * percentScale * displayScale + scale / 2n) / scale;
const whole = rounded / displayScale;
const fraction = rounded % displayScale;
if (fractionDigits === 0) {
return `${whole}%`;
}
return `${whole}.${fraction.toString().padStart(fractionDigits, "0")}%`;
}
Error Handling
Validate user-selected amounts before calling state-changing methods:
const ltv = client.quote.calculateLtv(request, pools, prices);
if (ltv.validationErrors.length > 0) {
return {
ok: false,
message: ltv.validationErrors.map((error) => error.message).join(" "),
};
}
Catch SDK errors at the boundary where the app can show user-facing copy,
retry, or log diagnostic context:
import { LiquidiumError, LiquidiumErrorCode } from "@liquidium/client";
try {
return await client.instantLoans.get({ ref });
} catch (error) {
if (error instanceof LiquidiumError) {
if (error.code === LiquidiumErrorCode.REQUEST_TIMEOUT) {
}
throw error;
}
throw error;
}
Use exported LiquidiumErrorCode values when the UI needs different copy for
timeout, transport, validation, or protocol failures. Quote validation failures
are returned in validationErrors; do not rely on thrown errors for normal quote
invalidity.
Wallet Adapter
The SDK uses a WalletAdapter for signing and transaction execution. Implement only the methods the selected flow needs.
Default authless instant loans do not need a WalletAdapter. Add one only
for advanced profile creation, signed borrow/withdraw, or automated transfer
execution.
import type { WalletAdapter } from "@liquidium/client";
const walletAdapter: WalletAdapter = {
signMessage: async ({ message }) => wallet.signMessage(message),
sendEthTransaction: async ({ transaction }) =>
wallet.sendTransaction(transaction),
};
Method selection:
signMessage: account creation, borrow, and withdraw flows (signs a Liquidium message)
sendBtcTransaction: transfer-path supply automation for BTC targets
sendEthTransaction: transfer-path automation for ETH targets and contract-interaction supply automation
Flows
Instant loan default flow
Use client.instantLoans.create(...) when the user should not create or manage
a Liquidium profile. The user supplies external destination addresses, receives
a short loan ID, then sends collateral to the generated deposit address.
Default app sequence:
- Fetch pools and prices for pool selection and optional quote display.
- Optionally call
client.quote.calculateLtv(...) to show current LTV and the collateral pool's max allowed LTV.
- Call
client.instantLoans.create(...) with direct base-unit amounts and external destination addresses.
- Persist or display
loan.ref as the primary recovery key.
- Show
loan.depositTarget for collateral deposit and loan.repayment.target plus loan.repayment.amount for repayment.
The default instant-loan flow does not need a wallet adapter. The user signs or
broadcasts only the external wallet transfer to the generated deposit or repay
target outside the SDK.
The deposit target and repayment target are not interchangeable. Collateral goes
to loan.depositTarget. Repayment goes to loan.repayment.target or
loan.repayTarget. If a UI has separate deposit and repay screens, each screen
must read the target for that exact phase instead of sharing one saved address.
const ltv = client.quote.calculateLtv(
{
collateralPoolId: btcPool.id,
borrowPoolId: usdtPool.id,
collateralAmount: 10_000_000n,
borrowAmount: 2_000_000n,
},
pools,
prices
);
const loan = await client.instantLoans.create({
collateralPoolId: btcPool.id,
borrowPoolId: usdtPool.id,
collateralAsset: "BTC",
borrowAsset: "USDT",
collateralAmount: 10_000_000n,
borrowAmount: 2_000_000n,
ltvMaxBps: ltv.maxAllowedLtvBps,
depositWindowSeconds: 3_600n,
borrowDestination: {
type: "External",
address: "0x2222222222222222222222222222222222222222",
},
refundDestination: { type: "External", address: "bc1qrefunddestination" },
});
const ref = loan.ref;
const depositTarget = loan.depositTarget;
const repayTarget = loan.repayTarget;
Create destinations are external-only. Pass an external address string or an
external account object: { type: "External", address: "..." }.
collateralAmount and borrowAmount are in each asset's base units. Use pool
decimals and the quote module when building UI inputs. Keep the initial loan
LTV under the SDK's instant-loan starting-LTV guard and set ltvMaxBps within
the collateral pool's accepted max-LTV range.
If the target is a native address, show target.address. If it is an ICRC
account, show target.account.
const depositAddress =
depositTarget.type === "nativeAddress"
? depositTarget.address
: depositTarget.account;
Transfer targets also include poolId, asset, chain, and action. Use
those fields to label and validate the UI before asking the user to send funds.
Restore a loan by ref whenever possible:
const loan = await client.instantLoans.get({ ref: "8Y9AQQ" });
const repayAmount = loan.repayment.amount;
const repayAddress =
loan.repayment.target.type === "nativeAddress"
? loan.repayment.target.address
: loan.repayment.target.account;
Use address lookup only as recovery when the user lost the loan reference:
const candidates = await client.instantLoans.findByAddress(
"bc1qrefunddestination"
);
const loan = await client.instantLoans.get({
loanId: candidates[0].loanId,
});
Reference lookup is canonical. Address lookup is discovery only: it may return
multiple candidates and should be followed by get({ loanId }) or
get({ ref }).
Do not use client.lending.borrow(...) for this flow. lending.borrow(...) is
the profile-based signed borrow primitive. Instant loans automate the borrow
after collateral arrives.
Instant loan status values are UI-facing:
awaiting_deposit: show loan.depositTarget and the deposit deadline
deposit_detected: keep polling and show a pending state
active: show loan.repayment.amount and loan.repayment.target
settling: keep polling and avoid duplicate user actions
closed: show final state and stop prompting for repayment
Advanced: create a profile
Only use this when the app intentionally manages Liquidium profiles. Do not add
profile creation to the default authless instant-loan flow.
Convenience method when the app already has wallet signing wired:
const profileId = await client.accounts.createProfile({
account: walletAddress,
chain: "ETH",
walletAdapter: {
signMessage: async ({ message }) => wallet.signMessage(message),
},
});
Prepare flow when you want explicit control over signing:
const createAction = await client.accounts.prepareCreateProfile({
account: walletAddress,
});
const signature = await wallet.signMessage(createAction.message);
const profileId = await createAction.submit({
signature,
chain: "ETH",
account: walletAddress,
});
prepareCreateProfile(...) normalizes the account and fetches the signing nonce;
it does not pre-check profile uniqueness. Handle existing profiles by catching
PROFILE_ALREADY_EXISTS from submission/canister validation and resolving the
profile instead of retrying the create flow.
Read market data and positions
const pools = await client.market.listPools();
const prices = await client.market.getAssetPrices();
const positions = await client.positions.listPositions(profileId);
const healthFactor = await client.positions.getHealthFactor(profileId);
For an aggregate position summary (availableBorrowsUsd, netWorthUsd,
currentLtvBps, healthFactor) plus a per-reserve USD breakdown:
const summary = await client.positions.getUserPositionSummary(profileId);
const reserves = await client.positions.getUserReserves(profileId);
Advanced profile-based quote-first borrow
Use this only for apps that already manage profiles and need signed borrow
execution. For the authless product flow, use the quote only for planning and
execute with client.instantLoans.create(...).
const pools = await client.market.listPools();
const prices = await client.market.getAssetPrices();
const quote = client.quote.getQuote(request, pools, prices);
const outflow = await client.lending.borrow({
profileId,
poolId: quote.borrowPoolId,
amount: quote.borrowAmount,
receiverAddress,
signerWalletAddress: walletAddress,
signerChain: "ETH",
signerWalletAdapter: {
signMessage: async ({ message }) => wallet.signMessage(message),
},
});
Advanced profile-based supply flow
Use this only for profile-based integrations that intentionally manage Liquidium
profiles. Use client.instantLoans for the default authless borrow UX.
const supplyFlow = await client.lending.supply({
profileId,
poolId,
action: "deposit",
});
if (
supplyFlow.type === "transfer" &&
supplyFlow.target.type === "nativeAddress"
) {
const depositAddress = supplyFlow.target.address;
}
await supplyFlow.submit({ txid: "<broadcast-txid>" });
For profile-based inflows, action: "deposit" and action: "repayment"
derive different targets. Use the supplyFlow.target returned by the exact
client.lending.supply(...) call for the action being executed. Do not use a
deposit flow, cached deposit address, or previous supplyFlow.target for a
repayment transfer.
supply(...) returns a receipt. When the SDK broadcast for you (wallet-adapter
path), supplyFlow.txid is populated. The SDK does not poll inflow status;
when you have a txid, you are responsible for polling confirmation state.
If the app wants the SDK to broadcast the transfer-path transaction, provide
walletAdapter, account, and amount:
const autoBroadcastFlow = await client.lending.supply({
profileId,
poolId,
action: "deposit",
amount: 100_000n,
account: walletAddress,
walletAdapter: {
sendBtcTransaction: async ({ toAddress, amountSats }) =>
wallet.sendBtcTransaction({ toAddress, amountSats }),
},
});
ETH stablecoin pools default to the deposit-address transfer path. With an ETH
wallet adapter, the SDK sends an ERC-20 transfer directly to the generated
deposit address:
const supplyFlow = await client.lending.supply({
profileId,
poolId,
action: "deposit",
account: walletAddress,
amount: 10_000_000n,
walletAdapter: {
sendEthTransaction: async ({ transaction }) =>
wallet.sendTransaction(transaction),
},
});
This default flow does not require apiBaseUrl or an EVM RPC. Use lower-level
getEvmSupplyContext(...) only if you are intentionally building the
contract-interaction flow.
ETH Stablecoin Deposit Addresses
ETH USDT/USDC deposit-address supply uses the ETH deposit-address canister
directly. It does not require apiBaseUrl for target resolution.
For mechanism: "transfer", the SDK resolves the deposit address by calling:
get_deposit_address(
{
owner: Principal.fromText(poolId),
subaccount: [
encodeInflowSubaccount({
action,
principal: Principal.fromText(profileId),
}),
],
},
[tokenContractAddress]
);
Important details:
owner is the selected pool principal (poolId)
subaccount is encoded from the Liquidium profileId and inflow action
tokenContractAddress is the ETH token contract address for USDT or USDC
- The SDK calls
get_deposit_address
- The user's EVM wallet address is not used to derive the deposit address
apiBaseUrl is not involved in this deposit-address lookup
If this returns DEPOSIT_ADDRESS_ERROR: unauthorized, do not diagnose it as a
missing API URL. Check that the selected pool principal is authorized by the ETH
deposit-address canister for the same deployment/environment.
For prod/mainnet, the SDK default ETH deposit-address canister is:
z5jz7-nyaaa-aaaar-qb6pq-cai.
When testing manually in the IC dashboard, use a pool principal from the same
deployment as the deposit-address canister.
Override the default route only when the app intentionally needs a specific
mechanism:
const contractInteractionFlow = await client.lending.supply({
profileId,
poolId,
action: "deposit",
mechanism: "contractInteraction",
account: walletAddress,
amount: 10_000_000n,
walletAdapter: {
sendEthTransaction: async ({ transaction }) =>
wallet.sendTransaction(transaction),
},
});
mechanism: "transfer" keeps the deposit-address path explicit. mechanism: "contractInteraction" requires apiBaseUrl, evmRpcUrl or evmPublicClient, account, amount, and sendEthTransaction.
Common Mistakes
- Treating profile lending as the default borrow flow. Use
client.instantLoans.create(...) for the authless product flow unless the user explicitly asks for profiles.
- Adding profile creation, signed borrow, or wallet adapter requirements to instant loans.
instantLoans.create(...) and instantLoans.get(...) do not need them.
- Confusing
quote.targetLtvBps with instant-loan ltvMaxBps. The quote target helps plan amounts; ltvMaxBps is validated by the instant-loan LTV guards.
new LiquidiumClient({}) uses the default Liquidium service configuration. Override apiBaseUrl for custom service deployments. Lower-level contract-interaction planning also needs evmRpcUrl or evmPublicClient. instantLoans.get(...), default ETH stablecoin deposit-address supply, borrow(...), and withdraw(...) do not use the service configuration.
- Prepare methods return signable actions, not completed actions.
prepareCreateProfile, prepareBorrow, and prepareWithdraw still need signing and submission.
- Build a wallet adapter with only the methods the selected flow needs. Avoid adding
signMessage, sendBtcTransaction, or sendEthTransaction unless the flow uses them.
- Do not
await client.quote.getQuote(...); it is synchronous once pools and prices are available.
- Check
quote.validationErrors before enabling borrow execution. Quote validation failures are returned in-band rather than thrown.
client.lending.supply(...) auto-routes by pool. BTC and ETH USDT pools currently resolve to deposit-address transfer targets by default; use mechanism only when intentionally overriding that route.
- Handle existing profiles explicitly when account creation can race with existing state. Do not rely on
prepareCreateProfile(...) to reject an existing profile before signing.
- Work from the public modules and names exported by
@liquidium/client. Do not invent SDK methods.
- After
borrow(...), treat outflow.id as the user-visible reference immediately. Do not assume outflow.txid is set on the first response; resolve it later via activities or history if you need the chain transaction id.
- History entries use
txids?: string[]; do not look for legacy direction-specific txid fields.
- ETH deposit-address
unauthorized is usually not an apiBaseUrl problem. The deposit-address lookup is a direct canister call. Check the poolId, ethDeposit canister ID, token address, and deployment/environment alignment first.
- Do not model instant loans as a
lending.supply(...) mechanism. Use client.instantLoans for the authless product flow and client.lending.supply(...) only for advanced profile-based supply/repay integrations.
- Do not trust address lookup as canonical loan state. Use it to find candidates, then hydrate the selected loan through
instantLoans.get(...).
- Do not confuse deposit/supply targets with repayment targets. They are generated for different inflow actions and may be different addresses/accounts.
- Do not render raw
rateDecimals = 27 fixed-point values as percentages. Format scaled rates first or the UI can show scientific notation such as 3.7e+24%.
Preferred Style
- Keep examples minimal and app-shaped
- Use convenience methods for end-to-end app flows
- Use prepare/sign/submit flows when the user asks for signing control or custom wallet orchestration
- Reuse the app's existing wallet provider instead of adding a parallel wallet framework
- Preserve the app's state management and fetch patterns
Defaults
- Prefer
client.instantLoans.create(...) for the simple authless borrow UX
- Start with
new LiquidiumClient({}) for market reads and authless instantLoans.create(...)
- Override
apiBaseUrl only when the app uses a custom Liquidium service deployment
- Add
evmRpcUrl or evmPublicClient when the requested flow reads Ethereum chain state
- Use
chain: "ETH" or chain: "BTC" exactly as required by the SDK
- Prefer a quote-first flow for advanced profile-based borrowing
- Prefer the BTC payment address when the wallet exposes both ordinals and payment addresses
Source Files
When unsure, check these first:
packages/client/README.md
README.md
packages/client/src/modules/instant-loans/instant-loans.ts
packages/client/src/modules/history/types.ts
packages/client/src/modules/instant-loans/types.ts
packages/client/src/modules/lending/types.ts
packages/client/src/modules/quote/types.ts
examples/instant-loans-flow/src/App.tsx
examples/instant-loans-flow/src/sdk-example.ts
examples/deposit-address-flow/src/dynamic-wallet.ts
examples/deposit-address-flow/src/sdk-example.ts
examples/contract-interaction-flow/src/dynamic-wallet.ts
examples/contract-interaction-flow/src/sdk-example.ts
examples/vite-react-dynamic/README.md
examples/vite-react-dynamic/src/lib/client.ts
examples/vite-react-dynamic/src/SdkMethodQueryPage.tsx
Useful Resources