@ember-finance/sdk 2.11.0-pre.1 → 2.11.0-pre.3

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.
@@ -15,12 +15,30 @@
15
15
  * @interface CoinPlacement
16
16
  */
17
17
  export interface CoinPlacement {
18
+ /**
19
+ * Stable identity for this placement, for a client to key a list on. A protocol can list the same coin at several venues — the same pair at two fee tiers, or the two tranches of one market — so protocol and label together do not identify a row. Survives a re-sync.
20
+ * @type {string}
21
+ * @memberof CoinPlacement
22
+ */
23
+ id: string;
18
24
  /**
19
25
  * Adapter id, e.g. \"bluefin-spot\"
20
26
  * @type {string}
21
27
  * @memberof CoinPlacement
22
28
  */
23
29
  protocol: string;
30
+ /**
31
+ * The protocol\'s display name, e.g. \"Current Finance\". Absent when the protocol is not in our catalogue yet — render `protocol` then.
32
+ * @type {string}
33
+ * @memberof CoinPlacement
34
+ */
35
+ protocolName?: string;
36
+ /**
37
+ * Icon for the protocol. Absent when the protocol is not in our catalogue yet.
38
+ * @type {string}
39
+ * @memberof CoinPlacement
40
+ */
41
+ protocolLogoUrl?: string;
24
42
  /**
25
43
  * Chain identifier as catalogued, e.g. \"sui-mainnet\".
26
44
  * @type {string}
@@ -1,2 +1 @@
1
- export declare const royco: import("../types.js").ProtocolAdapter;
2
1
  export declare const openCover: import("../types.js").ProtocolAdapter;
@@ -1,15 +1,8 @@
1
1
  import { createEvmVenueAdapter } from "./factory.js";
2
- // EVM protocols whose position IS the token the account holds.
2
+ // EVM protocols whose position IS the token the account holds, one for one, so
3
+ // the amount is that token's `balanceOf(account)`.
3
4
  //
4
- // A Royco wrapped vault and an OpenCover cover vault both hand the depositor a
5
- // share token, so the amount is its `balanceOf(account)` and neither needs
6
- // protocol-specific logic. Their venues are hand-maintained rows: neither
7
- // exposes a registry we can sweep without credentials.
8
- //
9
- // Pendle is not here — its PT/YT/LP are not 1:1 with the receipt coin, so it
10
- // needs its own conversion. See ./pendle.ts.
11
- //
12
- // They stay separate registrations so pointers, failures and reporting are
13
- // attributed per protocol.
14
- export const royco = createEvmVenueAdapter("royco");
5
+ // Neither Pendle nor Royco qualifies. Pendle's PT/YT/LP are not 1:1 with the
6
+ // receipt coin, and a Royco tranche vault issues 18-decimal shares that convert
7
+ // through its own claims struct. See ./pendle.ts and ./royco.ts.
15
8
  export const openCover = createEvmVenueAdapter("opencover");
@@ -2,7 +2,8 @@ export * from "./factory.js";
2
2
  export { alphalend } from "./alphalend.js";
3
3
  export { bluefinSpot } from "./bluefin-spot.js";
4
4
  export { current } from "./current.js";
5
- export { openCover, royco } from "./evm-protocols.js";
5
+ export { openCover } from "./evm-protocols.js";
6
+ export { royco } from "./royco.js";
6
7
  export { navi } from "./navi.js";
7
8
  export { createPendleAdapter, pendle } from "./pendle.js";
8
9
  export { suilend } from "./suilend.js";
@@ -2,7 +2,8 @@ import { registerAdapter } from "../registry.js";
2
2
  import { alphalend } from "./alphalend.js";
3
3
  import { bluefinSpot } from "./bluefin-spot.js";
4
4
  import { current } from "./current.js";
5
- import { openCover, royco } from "./evm-protocols.js";
5
+ import { openCover } from "./evm-protocols.js";
6
+ import { royco } from "./royco.js";
6
7
  import { navi } from "./navi.js";
7
8
  import { pendle } from "./pendle.js";
8
9
  import { suilend } from "./suilend.js";
@@ -10,7 +11,8 @@ export * from "./factory.js";
10
11
  export { alphalend } from "./alphalend.js";
11
12
  export { bluefinSpot } from "./bluefin-spot.js";
12
13
  export { current } from "./current.js";
13
- export { openCover, royco } from "./evm-protocols.js";
14
+ export { openCover } from "./evm-protocols.js";
15
+ export { royco } from "./royco.js";
14
16
  export { navi } from "./navi.js";
15
17
  export { createPendleAdapter, pendle } from "./pendle.js";
16
18
  export { suilend } from "./suilend.js";
@@ -0,0 +1,2 @@
1
+ import { ProtocolAdapter } from "../types.js";
2
+ export declare const royco: ProtocolAdapter;
@@ -0,0 +1,49 @@
1
+ import { asContractAddress, decodeUint256, encodeBalanceOf } from "../evm.js";
2
+ /** `convertToAssets(uint256)` */
3
+ const CONVERT_TO_ASSETS = "0x07a2d13a";
4
+ const WORD = 64;
5
+ /**
6
+ * What `account` holds at one Royco tranche vault, in base units of `ref.coin`.
7
+ */
8
+ async function trancheAssets(ref, account, ctx) {
9
+ if (!ctx.evm)
10
+ throw new Error("no evm reader configured");
11
+ const chainId = ref.chain.chainId;
12
+ if (chainId === undefined) {
13
+ throw new Error(`royco placement ${ref.venue} has no chainId`);
14
+ }
15
+ const vault = asContractAddress(ref.shareToken ?? ref.venue);
16
+ const shares = decodeUint256(await ctx.evm.call(chainId, vault, encodeBalanceOf(account), ref.rpcUrl));
17
+ if (shares === 0n)
18
+ return undefined;
19
+ // A tranche vault is not ERC-4626 despite the selector: convertToAssets
20
+ // returns AssetClaims { stAssets, jtAssets, nav }. The first two are the
21
+ // position in the deposit token's own decimals and are what the holder can
22
+ // claim; nav is a USD figure on a different scale. Taking one word — the
23
+ // obvious reading of a 4626 — reports a fraction of the position.
24
+ const raw = await ctx.evm.call(chainId, vault, `${CONVERT_TO_ASSETS}${shares.toString(16).padStart(WORD, "0")}`, ref.rpcUrl);
25
+ const body = raw.startsWith("0x") ? raw.slice(2) : raw;
26
+ if (body.length < WORD * 3) {
27
+ throw new Error(`royco: convertToAssets returned ${body.length / 2} bytes for ${ref.venue}`);
28
+ }
29
+ const stAssets = BigInt(`0x${body.slice(0, WORD)}`);
30
+ const jtAssets = BigInt(`0x${body.slice(WORD, WORD * 2)}`);
31
+ return stAssets + jtAssets;
32
+ }
33
+ export const royco = {
34
+ id: "royco",
35
+ chain: "evm",
36
+ async discover(coin, ctx) {
37
+ return ctx.pointers.placements("royco", coin);
38
+ },
39
+ async read(refs, account, ctx) {
40
+ const readAt = new Date().toISOString();
41
+ const resolved = await Promise.all(refs.map(async (ref) => {
42
+ const amount = await trancheAssets(ref, account, ctx);
43
+ if (amount === undefined)
44
+ return undefined;
45
+ return { ...ref, amount: amount.toString(), readAt };
46
+ }));
47
+ return resolved.filter((p) => p !== undefined);
48
+ }
49
+ };
@@ -66,6 +66,7 @@ export function httpPointerSource(options = {}) {
66
66
  // ever runs on its own chain, so a server that named it again could
67
67
  // only ever disagree.
68
68
  return (body.placements ?? []).map(placement => ({
69
+ id: placement.id,
69
70
  protocol: placement.protocol,
70
71
  chain: {
71
72
  type: coin.chain.type,
@@ -23,6 +23,13 @@ export interface ReceiptCoin {
23
23
  export type PointerOrigin = "Registry" | "Manual";
24
24
  /** Somewhere a receipt coin is listed. Carries no amount. */
25
25
  export interface PlacementRef {
26
+ /**
27
+ * Stable identity for this placement — the right thing to key a list on.
28
+ * A protocol can list the same coin at several venues (the same pair at two
29
+ * fee tiers, the two tranches of one market), so protocol and label
30
+ * together do not identify a row.
31
+ */
32
+ id?: string;
26
33
  protocol: ProtocolId;
27
34
  chain: ChainRef;
28
35
  /** Pool, market or vault address. */
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@ember-finance/sdk",
3
3
  "description": "Ember Protocol SDK",
4
- "version": "2.11.0-pre.1",
4
+ "version": "2.11.0-pre.3",
5
5
  "type": "module",
6
6
  "module": "./dist/index.js",
7
7
  "main": "./dist/index.js",