odin-connect 1.1.3 → 1.2.0

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.
@@ -29,7 +29,7 @@
29
29
  }
30
30
  },
31
31
  "..": {
32
- "version": "1.1.2",
32
+ "version": "1.1.3",
33
33
  "license": "ISC",
34
34
  "dependencies": {
35
35
  "@apimatic/json-bigint": "^1.2.0",
package/dist/index.d.ts CHANGED
@@ -5,4 +5,5 @@ export type { BaseToken as OdinBaseToken, Token as OdinToken, TokenWithBalance a
5
5
  export type { Activity as OdinActivity } from "./models/activity";
6
6
  export type { Achievement as OdinAchievement, AchievementCategory as OdinAchievementCategory, } from "./models/achievement";
7
7
  export * as OdinUtils from "./utils";
8
+ export type { ConnectedUser as OdinConnectedUser } from "./services/connected-user";
8
9
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAC5D,YAAY,EAAE,IAAI,IAAI,QAAQ,EAAE,MAAM,eAAe,CAAC;AACtD,YAAY,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/D,YAAY,EACV,SAAS,IAAI,aAAa,EAC1B,KAAK,IAAI,SAAS,EAClB,gBAAgB,IAAI,oBAAoB,GACzC,MAAM,gBAAgB,CAAC;AACxB,YAAY,EAAE,QAAQ,IAAI,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAClE,YAAY,EACV,WAAW,IAAI,eAAe,EAC9B,mBAAmB,IAAI,uBAAuB,GAC/C,MAAM,sBAAsB,CAAC;AAC9B,OAAO,KAAK,SAAS,MAAM,SAAS,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAC5D,YAAY,EAAE,IAAI,IAAI,QAAQ,EAAE,MAAM,eAAe,CAAC;AACtD,YAAY,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/D,YAAY,EACV,SAAS,IAAI,aAAa,EAC1B,KAAK,IAAI,SAAS,EAClB,gBAAgB,IAAI,oBAAoB,GACzC,MAAM,gBAAgB,CAAC;AACxB,YAAY,EAAE,QAAQ,IAAI,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAClE,YAAY,EACV,WAAW,IAAI,eAAe,EAC9B,mBAAmB,IAAI,uBAAuB,GAC/C,MAAM,sBAAsB,CAAC;AAC9B,OAAO,KAAK,SAAS,MAAM,SAAS,CAAC;AACrC,YAAY,EAAE,aAAa,IAAI,iBAAiB,EAAE,MAAM,2BAA2B,CAAC"}
@@ -17,7 +17,7 @@ export type PaginatedResponse<T> = {
17
17
  page: number;
18
18
  limit: number;
19
19
  };
20
- export declare class OdinApi {
20
+ export declare class OdinApiClient {
21
21
  private _apiKey;
22
22
  private _httpClient;
23
23
  readonly BASE_URL: string;
@@ -1 +1 @@
1
- {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../src/services/api.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAC5C,OAAO,EAAE,KAAK,EAAoB,MAAM,iBAAiB,CAAC;AAC1D,OAAO,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC;AAGtC,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAQ5D,MAAM,MAAM,UAAU,GAAG;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,IAAI,GAAG;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,KAAK,GAAG,MAAM,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,iBAAiB,CAAC,CAAC,IAAI;IACjC,IAAI,EAAE,aAAa,CAAC,CAAC,CAAC,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,qBAAa,OAAO;IAClB,OAAO,CAAC,OAAO,CAAuB;IACtC,OAAO,CAAC,WAAW,CAAa;IAChC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;gBAEd,GAAG,GAAE,MAAM,GAAG,KAAc;IAKxC,OAAO,CAAC,EAAE,EAAE,MAAM;IAIZ,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU;IAW3D,SAAS,CACP,UAAU,EAAE,UAAU,EACtB,IAAI,GAAE,IAAgD;IAaxD,QAAQ,CAAC,EAAE,EAAE,MAAM;IAIb,WAAW,CAAC,KAAK,EAAE,IAAI;IAqC7B,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI;cAKJ,KAAK;;IAsB9C,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU;IAWnD,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU;;;mBAIhD,KAAK;6BACK,MAAM;qCACE,MAAM;;eAlI9B,MAAM;cACP,MAAM;eACL,MAAM;;IAiJP,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU;;;;;eAnJzD,MAAM;cACP,MAAM;eACL,MAAM;;IAmKP,mBAAmB,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU;IAWnE,IAAI,MAAM,CAAC,GAAG,EAAE,MAAM,EAErB;IAED,IAAI,MAAM,IAAI,MAAM,GAAG,IAAI,CAE1B;CACF"}
1
+ {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../src/services/api.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAC5C,OAAO,EAAE,KAAK,EAAoB,MAAM,iBAAiB,CAAC;AAC1D,OAAO,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC;AAGtC,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAQ5D,MAAM,MAAM,UAAU,GAAG;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,IAAI,GAAG;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,KAAK,GAAG,MAAM,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,iBAAiB,CAAC,CAAC,IAAI;IACjC,IAAI,EAAE,aAAa,CAAC,CAAC,CAAC,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,qBAAa,aAAa;IACxB,OAAO,CAAC,OAAO,CAAuB;IACtC,OAAO,CAAC,WAAW,CAAa;IAChC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;gBAEd,GAAG,GAAE,MAAM,GAAG,KAAc;IAKxC,OAAO,CAAC,EAAE,EAAE,MAAM;IAIZ,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU;IAW3D,SAAS,CACP,UAAU,EAAE,UAAU,EACtB,IAAI,GAAE,IAAgD;IAaxD,QAAQ,CAAC,EAAE,EAAE,MAAM;IAIb,WAAW,CAAC,KAAK,EAAE,IAAI;IAqC7B,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI;cAKJ,KAAK;;IAsB9C,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU;IAWnD,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU;;;mBAIhD,KAAK;6BACK,MAAM;qCACE,MAAM;;eAlI9B,MAAM;cACP,MAAM;eACL,MAAM;;IAiJP,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU;;;;;eAnJzD,MAAM;cACP,MAAM;eACL,MAAM;;IAmKP,mBAAmB,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU;IAWnE,IAAI,MAAM,CAAC,GAAG,EAAE,MAAM,EAErB;IAED,IAAI,MAAM,IAAI,MAAM,GAAG,IAAI,CAE1B;CACF"}
@@ -5,7 +5,7 @@ const BASE_URL_ENV = {
5
5
  prod: "https://api.odin.fun/v1",
6
6
  local: "https://api.odin.fun/dev",
7
7
  };
8
- export class OdinApi {
8
+ export class OdinApiClient {
9
9
  _apiKey = null;
10
10
  _httpClient;
11
11
  BASE_URL;
@@ -1,20 +1,18 @@
1
1
  import { beforeAll, describe, expect, it, vi } from "vitest";
2
- import { OdinApi } from "./api";
2
+ import { OdinApiClient } from "./api";
3
3
  describe("ApiClient", () => {
4
4
  let api;
5
5
  beforeAll(() => {
6
- api = new OdinApi("dev");
7
- // You can add tests here to verify the functionality of OdinApi methods.
8
- // For example, you might want to mock HTTP requests and check responses.
6
+ api = new OdinApiClient("dev");
9
7
  });
10
- it("should create an instance of OdinApi", () => {
11
- expect(api).toBeInstanceOf(OdinApi);
8
+ it("should create an instance of OdinApiClient", () => {
9
+ expect(api).toBeInstanceOf(OdinApiClient);
12
10
  });
13
11
  it("it should have the correct base URL for dev environment", () => {
14
12
  expect(api.BASE_URL).toBe("https://api.odin.fun/dev");
15
13
  });
16
14
  it("it should have the correct base URL for prod environment", () => {
17
- const prodApi = new OdinApi("prod");
15
+ const prodApi = new OdinApiClient("prod");
18
16
  expect(prodApi.BASE_URL).toBe("https://api.odin.fun/v1");
19
17
  });
20
18
  it("it should get user by ID", async () => {
@@ -0,0 +1,65 @@
1
+ import { OdinApiClient } from "./api";
2
+ import { AppInitOptions } from "./connect";
3
+ import { WindowClient } from "./window";
4
+ export interface SellOptions {
5
+ principal: string;
6
+ token: string;
7
+ tokenAmount: bigint;
8
+ }
9
+ export interface BuyOptions {
10
+ principal: string;
11
+ token: string;
12
+ btcAmount: bigint;
13
+ }
14
+ export interface TransferOptions {
15
+ principal: string;
16
+ token: string;
17
+ amount: bigint;
18
+ destination: string;
19
+ }
20
+ export interface AddLiquidityOptions {
21
+ principal: string;
22
+ btcAmount: bigint;
23
+ token: string;
24
+ }
25
+ export interface RemoveLiquidityOptions {
26
+ principal: string;
27
+ lpAmount: bigint;
28
+ token: string;
29
+ }
30
+ export interface SwapOptions {
31
+ principal: string;
32
+ fromToken: string;
33
+ toToken: string;
34
+ fromAmount: bigint;
35
+ }
36
+ export interface CreateTokenParams {
37
+ principal: string;
38
+ name: string;
39
+ ticker: string;
40
+ image: File;
41
+ description?: string;
42
+ website?: string;
43
+ twitter?: string;
44
+ telegram?: string;
45
+ buy?: bigint;
46
+ discount?: string;
47
+ }
48
+ export declare class OdinCanisterClient {
49
+ private _window;
50
+ private _appInfo;
51
+ private _api;
52
+ origin: string;
53
+ constructor(windowClient: WindowClient, apiClient: OdinApiClient, appInfo: AppInitOptions, origin: string);
54
+ get appInfo(): AppInitOptions;
55
+ private createUrl;
56
+ private baseAction;
57
+ sell({ token, tokenAmount, principal }: SellOptions): Promise<boolean>;
58
+ buy({ principal, token, btcAmount }: BuyOptions): Promise<boolean>;
59
+ transfer({ principal, token, amount, destination }: TransferOptions): Promise<boolean>;
60
+ addLiquidity({ principal, btcAmount, token }: AddLiquidityOptions): Promise<boolean>;
61
+ removeLiquidity({ principal, lpAmount, token }: RemoveLiquidityOptions): Promise<boolean>;
62
+ swap({ principal, fromToken: from, toToken: to, fromAmount }: SwapOptions): Promise<boolean>;
63
+ createToken({ image, ...params }: CreateTokenParams): Promise<boolean>;
64
+ }
65
+ //# sourceMappingURL=canister.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"canister.d.ts","sourceRoot":"","sources":["../../src/services/canister.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AACtC,OAAO,EAAE,cAAc,EAAW,MAAM,WAAW,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAExC,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,mBAAmB;IAClC,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,sBAAsB;IACrC,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,IAAI,CAAC;IACZ,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,OAAO,CAAe;IAC9B,OAAO,CAAC,QAAQ,CAAiB;IACjC,OAAO,CAAC,IAAI,CAAgB;IAC5B,MAAM,EAAE,MAAM,CAAC;gBAGb,YAAY,EAAE,YAAY,EAC1B,SAAS,EAAE,aAAa,EACxB,OAAO,EAAE,cAAc,EACvB,MAAM,EAAE,MAAM;IAQhB,IAAI,OAAO,mBAEV;IAED,OAAO,CAAC,SAAS;IASjB,OAAO,CAAC,UAAU;IAuDlB,IAAI,CAAC,EAAE,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,EAAE,WAAW;IAiBnD,GAAG,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,EAAE,UAAU;IAiB/C,QAAQ,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,EAAE,eAAe;IAkBnE,YAAY,CAAC,EAAE,SAAS,EAAE,SAAS,EAAE,KAAK,EAAE,EAAE,mBAAmB;IAiBjE,eAAe,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE,sBAAsB;IAiBtE,IAAI,CAAC,EAAE,SAAS,EAAE,SAAS,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,UAAU,EAAE,EAAE,WAAW;IAkBnE,WAAW,CAAC,EAAE,KAAK,EAAE,GAAG,MAAM,EAAE,EAAE,iBAAiB;CAyC1D"}
@@ -0,0 +1,191 @@
1
+ import { createTokenValidators } from "../utils";
2
+ export class OdinCanisterClient {
3
+ _window;
4
+ _appInfo;
5
+ _api;
6
+ origin;
7
+ constructor(windowClient, apiClient, appInfo, origin) {
8
+ this._window = windowClient;
9
+ this._api = apiClient;
10
+ this._appInfo = appInfo;
11
+ this.origin = origin;
12
+ }
13
+ get appInfo() {
14
+ return this._appInfo;
15
+ }
16
+ createUrl(path) {
17
+ const url = new URL(`${this.origin}/${path}`);
18
+ if (this._appInfo?.name) {
19
+ url.searchParams.append("app_name", this._appInfo.name);
20
+ }
21
+ url.searchParams.append("referrer", window.location.origin);
22
+ return url;
23
+ }
24
+ baseAction({ params, odinPath, receivedMessageFromOrigin, resolve: resolveMessages, }) {
25
+ return new Promise((resolve, reject) => {
26
+ const handleMessage = async (event) => {
27
+ if (event.origin === this.origin &&
28
+ event.data.path === "/" + odinPath) {
29
+ window.removeEventListener("message", handleMessage);
30
+ if (typeof receivedMessageFromOrigin === "function"
31
+ ? receivedMessageFromOrigin(event.data.message)
32
+ : receivedMessageFromOrigin === event.data.message) {
33
+ resolve(resolveMessages.success(event.data.message));
34
+ }
35
+ else {
36
+ reject(new Error(resolveMessages.failure));
37
+ }
38
+ }
39
+ };
40
+ const url = this.createUrl(odinPath);
41
+ for (const key in params) {
42
+ // exclude undefined params
43
+ if (params[key]) {
44
+ url.searchParams.append(key, params[key]);
45
+ }
46
+ }
47
+ const opened = this._window.open(url);
48
+ if (!opened || opened.closed || typeof opened.closed === "undefined") {
49
+ reject(new Error(resolveMessages.didnotopen ??
50
+ `Failed to open ${odinPath} window, please always allow popups and try again`));
51
+ return;
52
+ }
53
+ window.addEventListener("message", handleMessage);
54
+ });
55
+ }
56
+ sell({ token, tokenAmount, principal }) {
57
+ return this.baseAction({
58
+ params: {
59
+ principal,
60
+ token,
61
+ amount: tokenAmount.toString(),
62
+ },
63
+ odinPath: "authorize/sell",
64
+ receivedMessageFromOrigin: "sold",
65
+ resolve: {
66
+ success: () => true,
67
+ failure: "Sell failed or was cancelled",
68
+ close: "User closed the window",
69
+ },
70
+ });
71
+ }
72
+ buy({ principal, token, btcAmount }) {
73
+ return this.baseAction({
74
+ params: {
75
+ principal,
76
+ token,
77
+ amount: btcAmount.toString(),
78
+ },
79
+ odinPath: "authorize/buy",
80
+ receivedMessageFromOrigin: "purchased",
81
+ resolve: {
82
+ success: () => true,
83
+ failure: "Purchase failed or was cancelled",
84
+ close: "User closed the window",
85
+ },
86
+ });
87
+ }
88
+ transfer({ principal, token, amount, destination }) {
89
+ return this.baseAction({
90
+ params: {
91
+ principal,
92
+ token,
93
+ amount: amount.toString(),
94
+ destination,
95
+ },
96
+ odinPath: "authorize/transfer",
97
+ receivedMessageFromOrigin: "transferred",
98
+ resolve: {
99
+ success: () => true,
100
+ failure: "Transfer failed or was cancelled",
101
+ close: "User closed the window",
102
+ },
103
+ });
104
+ }
105
+ addLiquidity({ principal, btcAmount, token }) {
106
+ return this.baseAction({
107
+ params: {
108
+ principal,
109
+ amount: btcAmount.toString(),
110
+ token,
111
+ },
112
+ odinPath: "authorize/add_liquidity",
113
+ receivedMessageFromOrigin: "addedLiquidity",
114
+ resolve: {
115
+ success: () => true,
116
+ failure: "Add liquidity failed or was cancelled",
117
+ close: "User closed the window",
118
+ },
119
+ });
120
+ }
121
+ removeLiquidity({ principal, lpAmount, token }) {
122
+ return this.baseAction({
123
+ params: {
124
+ principal,
125
+ amount: lpAmount.toString(),
126
+ token,
127
+ },
128
+ odinPath: "authorize/remove_liquidity",
129
+ receivedMessageFromOrigin: "removedLiquidity",
130
+ resolve: {
131
+ success: () => true,
132
+ failure: "Remove liquidity failed or was cancelled",
133
+ close: "User closed the window",
134
+ },
135
+ });
136
+ }
137
+ swap({ principal, fromToken: from, toToken: to, fromAmount }) {
138
+ return this.baseAction({
139
+ params: {
140
+ principal,
141
+ from,
142
+ to,
143
+ amount: fromAmount.toString(),
144
+ },
145
+ odinPath: "authorize/swap",
146
+ receivedMessageFromOrigin: "swapped",
147
+ resolve: {
148
+ success: () => true,
149
+ failure: "Swap failed or was cancelled",
150
+ close: "User closed the window",
151
+ },
152
+ });
153
+ }
154
+ async createToken({ image, ...params }) {
155
+ // check if token field param validators exist and run them
156
+ for (const key in createTokenValidators) {
157
+ if (key in params) {
158
+ const field = key;
159
+ const errors = createTokenValidators[field]?.(params[key] || null);
160
+ if (errors) {
161
+ throw new Error(errors);
162
+ }
163
+ }
164
+ }
165
+ // additional validations for discount code
166
+ if (params.discount) {
167
+ if (!/^[A-Za-z0-9]{10}$/.test(params.discount)) {
168
+ throw new Error("Discount code must be alphanumeric and exactly 10 characters long.");
169
+ }
170
+ }
171
+ const imageUrl = await this._api.uploadImage(image);
172
+ const result = await this.baseAction({
173
+ params: {
174
+ ...params,
175
+ image: imageUrl,
176
+ buy: params.buy?.toString(),
177
+ },
178
+ odinPath: "authorize/create_token",
179
+ receivedMessageFromOrigin: "tokenCreated",
180
+ resolve: {
181
+ success: () => true,
182
+ failure: "Token creation failed or was cancelled",
183
+ close: "User closed the window",
184
+ },
185
+ });
186
+ if (!result) {
187
+ throw new Error("Token creation failed. Please try again.");
188
+ }
189
+ return true;
190
+ }
191
+ }
@@ -1,10 +1,12 @@
1
1
  import { DelegationIdentity } from "@dfinity/identity";
2
- import { OdinApi } from "./api";
2
+ import { OdinApiClient } from "./api";
3
+ import { AddLiquidityOptions, BuyOptions, OdinCanisterClient, RemoveLiquidityOptions, SellOptions, TransferOptions } from "./canister";
3
4
  export declare class ConnectedUser {
4
5
  private _identity;
5
6
  private _api;
6
7
  private _principal;
7
- constructor(principal: string, identity: DelegationIdentity | null, api: OdinApi);
8
+ private _odin;
9
+ constructor(principal: string, identity: DelegationIdentity | null, api: OdinApiClient, odin: OdinCanisterClient);
8
10
  getIdentity(): DelegationIdentity | null;
9
11
  getUser(): Promise<import("..").OdinUser>;
10
12
  getBalances(pagination: {
@@ -25,5 +27,10 @@ export declare class ConnectedUser {
25
27
  page: number;
26
28
  limit: number;
27
29
  }>;
30
+ sell(params: Omit<SellOptions, "principal">): Promise<boolean>;
31
+ buy(params: Omit<BuyOptions, "principal">): Promise<boolean>;
32
+ addLiquidity(params: Omit<AddLiquidityOptions, "principal">): Promise<boolean>;
33
+ removeLiquidity(params: Omit<RemoveLiquidityOptions, "principal">): Promise<boolean>;
34
+ transfer(params: Omit<TransferOptions, "principal">): Promise<boolean>;
28
35
  }
29
36
  //# sourceMappingURL=connect-user.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"connect-user.d.ts","sourceRoot":"","sources":["../../src/services/connect-user.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AAGhC,qBAAa,aAAa;IACxB,OAAO,CAAC,SAAS,CAA4B;IAC7C,OAAO,CAAC,IAAI,CAAU;IACtB,OAAO,CAAC,UAAU,CAAS;gBAGzB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,kBAAkB,GAAG,IAAI,EACnC,GAAG,EAAE,OAAO;IAOd,WAAW,IAAI,kBAAkB,GAAG,IAAI;IAIxC,OAAO;IAIP,WAAW,CAAC,UAAU,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE;IAIvD,aAAa,CAAC,UAAU,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE;;;;;;;;;;;CAK1D"}
1
+ {"version":3,"file":"connect-user.d.ts","sourceRoot":"","sources":["../../src/services/connect-user.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AACtC,OAAO,EACL,mBAAmB,EACnB,UAAU,EACV,kBAAkB,EAClB,sBAAsB,EACtB,WAAW,EACX,eAAe,EAChB,MAAM,YAAY,CAAC;AAEpB,qBAAa,aAAa;IACxB,OAAO,CAAC,SAAS,CAA4B;IAC7C,OAAO,CAAC,IAAI,CAAgB;IAC5B,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,KAAK,CAAqB;gBAGhC,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,kBAAkB,GAAG,IAAI,EACnC,GAAG,EAAE,aAAa,EAClB,IAAI,EAAE,kBAAkB;IAQ1B,WAAW,IAAI,kBAAkB,GAAG,IAAI;IAIxC,OAAO;IAIP,WAAW,CAAC,UAAU,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE;IAIvD,aAAa,CAAC,UAAU,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE;;;;;;;;;;;IAMzD,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,WAAW,EAAE,WAAW,CAAC;IAO3C,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,UAAU,EAAE,WAAW,CAAC;IAOzC,YAAY,CAAC,MAAM,EAAE,IAAI,CAAC,mBAAmB,EAAE,WAAW,CAAC;IAO3D,eAAe,CAAC,MAAM,EAAE,IAAI,CAAC,sBAAsB,EAAE,WAAW,CAAC;IAOjE,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,eAAe,EAAE,WAAW,CAAC;CAMpD"}
@@ -2,10 +2,12 @@ export class ConnectedUser {
2
2
  _identity;
3
3
  _api;
4
4
  _principal;
5
- constructor(principal, identity, api) {
5
+ _odin;
6
+ constructor(principal, identity, api, odin) {
6
7
  this._principal = principal;
7
8
  this._identity = identity;
8
9
  this._api = api;
10
+ this._odin = odin;
9
11
  }
10
12
  getIdentity() {
11
13
  return this._identity;
@@ -19,4 +21,35 @@ export class ConnectedUser {
19
21
  getUserTokens(pagination) {
20
22
  return this._api.getUserTokens(this._principal, pagination);
21
23
  }
24
+ /// others
25
+ sell(params) {
26
+ return this._odin.sell({
27
+ ...params,
28
+ principal: this._principal,
29
+ });
30
+ }
31
+ buy(params) {
32
+ return this._odin.buy({
33
+ ...params,
34
+ principal: this._principal,
35
+ });
36
+ }
37
+ addLiquidity(params) {
38
+ return this._odin.addLiquidity({
39
+ ...params,
40
+ principal: this._principal,
41
+ });
42
+ }
43
+ removeLiquidity(params) {
44
+ return this._odin.removeLiquidity({
45
+ ...params,
46
+ principal: this._principal,
47
+ });
48
+ }
49
+ transfer(params) {
50
+ return this._odin.transfer({
51
+ ...params,
52
+ principal: this._principal,
53
+ });
54
+ }
22
55
  }
@@ -1,16 +1,15 @@
1
- import { OdinApi } from "./api";
2
- import { ConnectedUser } from "./connect-user";
1
+ import { OdinApiClient } from "./api";
2
+ import { ConnectedUser } from "./connected-user";
3
3
  import { Environment } from "../models/environment";
4
- interface AppInitOptions {
4
+ import { WindowClientSettings } from "./window";
5
+ import { OdinCanisterClient } from "./canister";
6
+ export interface AppInitOptions {
5
7
  name: string;
6
8
  icon?: string;
7
9
  env?: Environment;
8
10
  }
9
11
  interface BaseConnectOptions {
10
- open?: {
11
- target: string;
12
- settings: string;
13
- };
12
+ open?: WindowClientSettings;
14
13
  requires_api?: boolean;
15
14
  }
16
15
  interface ConnectOptionsWithDelegation extends BaseConnectOptions {
@@ -23,78 +22,20 @@ interface ConnectOptionsWithoutDelegation extends BaseConnectOptions {
23
22
  session_key?: never;
24
23
  }
25
24
  type ConnectOptions = ConnectOptionsWithDelegation | ConnectOptionsWithoutDelegation;
26
- interface BuyOptions {
27
- principal: string;
28
- token: string;
29
- btcAmount: bigint;
30
- }
31
- interface SellOptions {
32
- principal: string;
33
- token: string;
34
- tokenAmount: bigint;
35
- }
36
- interface TransferOptions {
37
- principal: string;
38
- token: string;
39
- amount: bigint;
40
- destination: string;
41
- }
42
- interface GetBalanceOptions {
43
- principal: string;
44
- pagination: {
45
- page: number;
46
- limit: number;
47
- };
48
- }
49
- interface AddLiquidityOptions {
50
- principal: string;
51
- btcAmount: bigint;
52
- token: string;
53
- }
54
- interface RemoveLiquidityOptions {
55
- principal: string;
56
- lpAmount: bigint;
57
- token: string;
58
- }
59
- interface SwapOptions {
60
- principal: string;
61
- fromToken: string;
62
- toToken: string;
63
- fromAmount: bigint;
64
- }
65
- interface CreateTokenParams {
66
- principal: string;
67
- name: string;
68
- ticker: string;
69
- image: File;
70
- description?: string;
71
- website?: string;
72
- twitter?: string;
73
- telegram?: string;
74
- buy?: bigint;
75
- discount?: string;
76
- }
77
25
  export declare class Connect {
78
26
  private _appInfo;
79
27
  private _api;
80
- private _windowSettings;
28
+ private _window;
29
+ private _odin;
81
30
  constructor(appInfo?: Partial<AppInitOptions>);
82
31
  private createUrl;
83
- private openWindow;
84
32
  get origin(): string;
85
- connect({ open, requires_api, requires_delegation, targets, }: ConnectOptions): Promise<ConnectedUser>;
86
- getBalances({ principal, pagination }: GetBalanceOptions): Promise<readonly import("..").OdinBalance[]>;
87
- get apiClient(): OdinApi;
33
+ get appInfo(): AppInitOptions | null;
34
+ connect({ open, requires_api, requires_delegation, targets, }?: ConnectOptions | undefined): Promise<ConnectedUser>;
35
+ get api(): OdinApiClient;
36
+ get odin(): OdinCanisterClient;
88
37
  get currentEnv(): "prod" | "dev" | "local";
89
- sell({ token, tokenAmount, principal }: SellOptions): Promise<boolean>;
90
- buy({ principal, token, btcAmount }: BuyOptions): Promise<boolean>;
91
- transfer({ principal, token, amount, destination }: TransferOptions): Promise<boolean>;
92
- addLiquidity({ principal, btcAmount, token }: AddLiquidityOptions): Promise<boolean>;
93
- removeLiquidity({ principal, lpAmount, token }: RemoveLiquidityOptions): Promise<boolean>;
94
- swap({ principal, fromToken: from, toToken: to, fromAmount }: SwapOptions): Promise<boolean>;
95
- createToken({ image, ...params }: CreateTokenParams): Promise<boolean>;
96
38
  hello(): void;
97
- private baseAction;
98
39
  }
99
40
  export {};
100
41
  //# sourceMappingURL=connect.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"connect.d.ts","sourceRoot":"","sources":["../../src/services/connect.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"connect.d.ts","sourceRoot":"","sources":["../../src/services/connect.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAoB,MAAM,OAAO,CAAC;AAOxD,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,WAAW,EAAW,MAAM,uBAAuB,CAAC;AAC7D,OAAO,EAAgB,oBAAoB,EAAE,MAAM,UAAU,CAAC;AAC9D,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAEhD,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,WAAW,CAAC;CACnB;AACD,UAAU,kBAAkB;IAE1B,IAAI,CAAC,EAAE,oBAAoB,CAAC;IAE5B,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED,UAAU,4BAA6B,SAAQ,kBAAkB;IAE/D,mBAAmB,EAAE,IAAI,CAAC;IAC1B,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,UAAU,+BAAgC,SAAQ,kBAAkB;IAClE,mBAAmB,CAAC,EAAE,KAAK,CAAC;IAC5B,OAAO,CAAC,EAAE,KAAK,CAAC;IAChB,WAAW,CAAC,EAAE,KAAK,CAAC;CACrB;AAED,KAAK,cAAc,GACf,4BAA4B,GAC5B,+BAA+B,CAAC;AAWpC,qBAAa,OAAO;IAClB,OAAO,CAAC,QAAQ,CAA+B;IAC/C,OAAO,CAAC,IAAI,CAAgB;IAC5B,OAAO,CAAC,OAAO,CAAe;IAC9B,OAAO,CAAC,KAAK,CAAqB;gBAEtB,OAAO,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC;IAkB7C,OAAO,CAAC,SAAS;IASjB,IAAI,MAAM,WAET;IAED,IAAI,OAAO,0BAEV;IAED,OAAO,CACL,EACE,IAAI,EACJ,YAAY,EACZ,mBAAmB,EACnB,OAAO,GACR,GAAE,cAAc,GAAG,SAGnB,GACA,OAAO,CAAC,aAAa,CAAC;IA2EzB,IAAI,GAAG,kBAEN;IAED,IAAI,IAAI,uBAEP;IAED,IAAI,UAAU,6BAEb;IAED,KAAK;CAGN"}
@@ -1,23 +1,23 @@
1
- import { OdinApi } from "./api";
2
- import { createTokenValidators } from "../utils";
1
+ import { OdinApiClient } from "./api";
3
2
  import { DelegationChain, DelegationIdentity, Ed25519KeyIdentity, } from "@dfinity/identity";
4
- import { ConnectedUser } from "./connect-user";
3
+ import { ConnectedUser } from "./connected-user";
5
4
  import { ORIGINS } from "../models/environment";
5
+ import { WindowClient } from "./window";
6
+ import { OdinCanisterClient } from "./canister";
6
7
  export class Connect {
7
8
  _appInfo = null;
8
9
  _api;
9
- _windowSettings;
10
+ _window;
11
+ _odin;
10
12
  constructor(appInfo) {
11
13
  this._appInfo = {
12
14
  env: "prod",
13
15
  name: "app_name",
14
16
  ...appInfo,
15
17
  };
16
- this._api = new OdinApi(this._appInfo.env === "prod" ? "prod" : "dev");
17
- this._windowSettings = {
18
- target: "_blank",
19
- settings: "",
20
- };
18
+ this._api = new OdinApiClient(this._appInfo.env === "prod" ? "prod" : "dev");
19
+ this._window = new WindowClient();
20
+ this._odin = new OdinCanisterClient(this._window, this._api, this._appInfo, ORIGINS[this._appInfo.env || "prod"]);
21
21
  }
22
22
  createUrl(path) {
23
23
  const url = new URL(`${this.origin}/${path}`);
@@ -27,16 +27,19 @@ export class Connect {
27
27
  url.searchParams.append("referrer", window.location.origin);
28
28
  return url;
29
29
  }
30
- openWindow(url) {
31
- return window.open(url, this._windowSettings?.target || "_blank", this._windowSettings?.settings);
32
- }
33
30
  get origin() {
34
31
  return ORIGINS[this._appInfo?.env || "prod"];
35
32
  }
36
- connect({ open, requires_api, requires_delegation, targets, }) {
33
+ get appInfo() {
34
+ return this._appInfo;
35
+ }
36
+ connect({ open, requires_api, requires_delegation, targets, } = {
37
+ requires_delegation: false,
38
+ requires_api: false,
39
+ }) {
37
40
  return new Promise((resolve, reject) => {
38
41
  if (open) {
39
- this._windowSettings = open;
42
+ this._window.settings = open;
40
43
  }
41
44
  const sessionKey = Ed25519KeyIdentity.generate();
42
45
  const handleMessage = async (event) => {
@@ -59,10 +62,10 @@ export class Connect {
59
62
  throw new Error("Delegation chain is missing");
60
63
  }
61
64
  const identity = DelegationIdentity.fromDelegation(sessionKey, DelegationChain.fromJSON(delegationChain));
62
- connectedUser = new ConnectedUser(principal, identity, this.apiClient);
65
+ connectedUser = new ConnectedUser(principal, identity, this.api, this._odin);
63
66
  }
64
67
  else {
65
- connectedUser = new ConnectedUser(principal, null, this.apiClient);
68
+ connectedUser = new ConnectedUser(principal, null, this.api, this._odin);
66
69
  }
67
70
  resolve(connectedUser);
68
71
  }
@@ -81,187 +84,22 @@ export class Connect {
81
84
  url.searchParams.append("requires_delegation", "1");
82
85
  const sessionString = btoa(JSON.stringify(sessionKey.toJSON()));
83
86
  url.searchParams.append("session_key", sessionString);
84
- url.searchParams.append("targets", targets.join(","));
87
+ url.searchParams.append("targets", targets?.join(",") || "");
85
88
  }
86
- this.openWindow(url);
89
+ this._window.open(url);
87
90
  window.addEventListener("message", handleMessage);
88
91
  });
89
92
  }
90
- async getBalances({ principal, pagination }) {
91
- if (!principal) {
92
- throw new Error("Principal is required to fetch balances");
93
- }
94
- return this._api.getBalances(principal, pagination);
95
- }
96
- get apiClient() {
93
+ get api() {
97
94
  return this._api;
98
95
  }
96
+ get odin() {
97
+ return this._odin;
98
+ }
99
99
  get currentEnv() {
100
100
  return this._appInfo?.env || "prod";
101
101
  }
102
- sell({ token, tokenAmount, principal }) {
103
- return this.baseAction({
104
- params: {
105
- principal,
106
- token,
107
- amount: tokenAmount.toString(),
108
- },
109
- odinPath: "authorize/sell",
110
- receivedMessageFromOrigin: "sold",
111
- resolve: {
112
- success: () => true,
113
- failure: "Sell failed or was cancelled",
114
- close: "User closed the window",
115
- },
116
- });
117
- }
118
- buy({ principal, token, btcAmount }) {
119
- return this.baseAction({
120
- params: {
121
- principal,
122
- token,
123
- amount: btcAmount.toString(),
124
- },
125
- odinPath: "authorize/buy",
126
- receivedMessageFromOrigin: "purchased",
127
- resolve: {
128
- success: () => true,
129
- failure: "Purchase failed or was cancelled",
130
- close: "User closed the window",
131
- },
132
- });
133
- }
134
- transfer({ principal, token, amount, destination }) {
135
- return this.baseAction({
136
- params: {
137
- principal,
138
- token,
139
- amount: amount.toString(),
140
- destination,
141
- },
142
- odinPath: "authorize/transfer",
143
- receivedMessageFromOrigin: "transferred",
144
- resolve: {
145
- success: () => true,
146
- failure: "Transfer failed or was cancelled",
147
- close: "User closed the window",
148
- },
149
- });
150
- }
151
- addLiquidity({ principal, btcAmount, token }) {
152
- return this.baseAction({
153
- params: {
154
- principal,
155
- amount: btcAmount.toString(),
156
- token,
157
- },
158
- odinPath: "authorize/add_liquidity",
159
- receivedMessageFromOrigin: "addedLiquidity",
160
- resolve: {
161
- success: () => true,
162
- failure: "Add liquidity failed or was cancelled",
163
- close: "User closed the window",
164
- },
165
- });
166
- }
167
- removeLiquidity({ principal, lpAmount, token }) {
168
- return this.baseAction({
169
- params: {
170
- principal,
171
- amount: lpAmount.toString(),
172
- token,
173
- },
174
- odinPath: "authorize/remove_liquidity",
175
- receivedMessageFromOrigin: "removedLiquidity",
176
- resolve: {
177
- success: () => true,
178
- failure: "Remove liquidity failed or was cancelled",
179
- close: "User closed the window",
180
- },
181
- });
182
- }
183
- swap({ principal, fromToken: from, toToken: to, fromAmount }) {
184
- return this.baseAction({
185
- params: {
186
- principal,
187
- from,
188
- to,
189
- amount: fromAmount.toString(),
190
- },
191
- odinPath: "authorize/swap",
192
- receivedMessageFromOrigin: "swapped",
193
- resolve: {
194
- success: () => true,
195
- failure: "Swap failed or was cancelled",
196
- close: "User closed the window",
197
- },
198
- });
199
- }
200
- async createToken({ image, ...params }) {
201
- // check if token field param validators exist and run them
202
- for (const key in createTokenValidators) {
203
- if (key in params) {
204
- const field = key;
205
- const errors = createTokenValidators[field]?.(params[key] || null);
206
- if (errors) {
207
- throw new Error(errors);
208
- }
209
- }
210
- }
211
- // additional validations for discount code
212
- if (params.discount) {
213
- if (!/^[A-Za-z0-9]{10}$/.test(params.discount)) {
214
- throw new Error("Discount code must be alphanumeric and exactly 10 characters long.");
215
- }
216
- }
217
- const imageUrl = await this._api.uploadImage(image);
218
- const result = await this.baseAction({
219
- params: {
220
- ...params,
221
- image: imageUrl,
222
- buy: params.buy?.toString(),
223
- },
224
- odinPath: "authorize/create_token",
225
- receivedMessageFromOrigin: "tokenCreated",
226
- resolve: {
227
- success: () => true,
228
- failure: "Token creation failed or was cancelled",
229
- close: "User closed the window",
230
- },
231
- });
232
- if (!result) {
233
- throw new Error("Token creation failed. Please try again.");
234
- }
235
- return true;
236
- }
237
102
  hello() {
238
103
  console.log("Hello from Odin Connect!");
239
104
  }
240
- baseAction({ params, odinPath, receivedMessageFromOrigin, resolve: resolveMessages, }) {
241
- return new Promise((resolve, reject) => {
242
- const handleMessage = async (event) => {
243
- if (event.origin === this.origin &&
244
- event.data.path === "/" + odinPath) {
245
- window.removeEventListener("message", handleMessage);
246
- if (typeof receivedMessageFromOrigin === "function"
247
- ? receivedMessageFromOrigin(event.data.message)
248
- : receivedMessageFromOrigin === event.data.message) {
249
- resolve(resolveMessages.success(event.data.message));
250
- }
251
- else {
252
- reject(new Error(resolveMessages.failure));
253
- }
254
- }
255
- };
256
- const url = this.createUrl(odinPath);
257
- for (const key in params) {
258
- // exclude undefined params
259
- if (params[key]) {
260
- url.searchParams.append(key, params[key]);
261
- }
262
- }
263
- this.openWindow(url);
264
- window.addEventListener("message", handleMessage);
265
- });
266
- }
267
105
  }
@@ -101,7 +101,7 @@ describe("Connect", () => {
101
101
  });
102
102
  it("should open the buy authorization window", () => {
103
103
  const openSpy = vi.spyOn(window, "open").mockImplementation(() => null);
104
- const result = connect.buy({
104
+ const result = connect.odin.buy({
105
105
  token: "2jjj",
106
106
  btcAmount: 20001n,
107
107
  principal: "test-principal",
@@ -122,7 +122,7 @@ describe("Connect", () => {
122
122
  });
123
123
  it("should open the sell authorization window", () => {
124
124
  const openSpy = vi.spyOn(window, "open").mockImplementation(() => null);
125
- const sellPromise = connect.sell({
125
+ const sellPromise = connect.odin.sell({
126
126
  token: "2jjj",
127
127
  tokenAmount: 32000n,
128
128
  principal: "test-principal",
@@ -143,7 +143,7 @@ describe("Connect", () => {
143
143
  });
144
144
  it("should handle rejected sell", () => {
145
145
  const openSpy = vi.spyOn(window, "open").mockImplementation(() => null);
146
- const sellPromise = connect.sell({
146
+ const sellPromise = connect.odin.sell({
147
147
  token: "2jjj",
148
148
  tokenAmount: 32000n,
149
149
  principal: "test-principal",
@@ -152,14 +152,14 @@ describe("Connect", () => {
152
152
  expect(true).toBe(false); // should not be called
153
153
  }, (e) => {
154
154
  expect(e).toBeInstanceOf(Error);
155
- expect(e.message).toContain("failed");
155
+ expect(e.message).toContain(/failed/i);
156
156
  });
157
157
  expect(openSpy).toHaveBeenCalled();
158
158
  simulateRejectMessage("authorize/sell");
159
159
  });
160
160
  it("should open the transfer authorization window", () => {
161
161
  const openSpy = vi.spyOn(window, "open").mockImplementation(() => null);
162
- const result = connect.transfer({
162
+ const result = connect.odin.transfer({
163
163
  token: "2jjj",
164
164
  amount: 45000n,
165
165
  destination: "to-principal",
@@ -181,7 +181,7 @@ describe("Connect", () => {
181
181
  });
182
182
  it("should handle rejected transfer", () => {
183
183
  const openSpy = vi.spyOn(window, "open").mockImplementation(() => null);
184
- const transferPromise = connect.transfer({
184
+ const transferPromise = connect.odin.transfer({
185
185
  token: "2jjj",
186
186
  amount: 45000n,
187
187
  destination: "to-principal",
@@ -190,14 +190,14 @@ describe("Connect", () => {
190
190
  transferPromise.then(() => expect(true).toBe(false), // should not be called
191
191
  (e) => {
192
192
  expect(e).toBeInstanceOf(Error);
193
- expect(e.message).toContain("failed");
193
+ expect(e.message).toContain(/failed/i);
194
194
  });
195
195
  expect(openSpy).toHaveBeenCalled();
196
196
  simulateRejectMessage("authorize/transfer");
197
197
  });
198
198
  it("should open the add liquidity authorization window", () => {
199
199
  const openSpy = vi.spyOn(window, "open").mockImplementation(() => null);
200
- const addLiquidityPromise = connect.addLiquidity({
200
+ const addLiquidityPromise = connect.odin.addLiquidity({
201
201
  token: "2jjj",
202
202
  btcAmount: 10000n,
203
203
  principal: "test-principal",
@@ -217,7 +217,7 @@ describe("Connect", () => {
217
217
  });
218
218
  it("should handle rejected add liquidity", () => {
219
219
  const openSpy = vi.spyOn(window, "open").mockImplementation(() => null);
220
- const addLiquidityPromise = connect.addLiquidity({
220
+ const addLiquidityPromise = connect.odin.addLiquidity({
221
221
  token: "2jjj",
222
222
  btcAmount: 10000n,
223
223
  principal: "test-principal",
@@ -225,14 +225,14 @@ describe("Connect", () => {
225
225
  addLiquidityPromise.then(() => expect(true).toBe(false), // should not be called
226
226
  (e) => {
227
227
  expect(e).toBeInstanceOf(Error);
228
- expect(e.message).toContain("failed");
228
+ expect(e.message).toContain(/failed/i);
229
229
  });
230
230
  expect(openSpy).toHaveBeenCalled();
231
231
  simulateRejectMessage("authorize/add_liquidity");
232
232
  });
233
233
  it("should open the remove liquidity authorization window", () => {
234
234
  const openSpy = vi.spyOn(window, "open").mockImplementation(() => null);
235
- const removeLiquidityPromise = connect.removeLiquidity({
235
+ const removeLiquidityPromise = connect.odin.removeLiquidity({
236
236
  token: "2jjj",
237
237
  lpAmount: 15000n,
238
238
  principal: "test-principal",
@@ -252,7 +252,7 @@ describe("Connect", () => {
252
252
  });
253
253
  it("should handle rejected remove liquidity", () => {
254
254
  const openSpy = vi.spyOn(window, "open").mockImplementation(() => null);
255
- const removeLiquidityPromise = connect.removeLiquidity({
255
+ const removeLiquidityPromise = connect.odin.removeLiquidity({
256
256
  token: "2jjj",
257
257
  lpAmount: 15000n,
258
258
  principal: "test-principal",
@@ -260,14 +260,14 @@ describe("Connect", () => {
260
260
  removeLiquidityPromise.then(() => expect(true).toBe(false), // should not be called
261
261
  (e) => {
262
262
  expect(e).toBeInstanceOf(Error);
263
- expect(e.message).toContain("failed");
263
+ expect(e.message).toContain(/failed/i);
264
264
  });
265
265
  expect(openSpy).toHaveBeenCalled();
266
266
  simulateRejectMessage("authorize/remove_liquidity");
267
267
  });
268
268
  it("should create a base action", async () => {
269
269
  const openSpy = vi.spyOn(window, "open").mockImplementation(() => null);
270
- const action = () => connect["baseAction"]({
270
+ const action = () => connect.odin["baseAction"]({
271
271
  params: { test: "param" },
272
272
  odinPath: "authorize/test_action",
273
273
  receivedMessageFromOrigin(message) {
@@ -294,7 +294,7 @@ describe("Connect", () => {
294
294
  simulateMessage("authorize/test_action", "OK");
295
295
  action().then(() => expect(true).toBe(false), (e) => {
296
296
  expect(e).toBeInstanceOf(Error);
297
- expect(e.message).toBe("test failed");
297
+ expect(e.message).toContain(/failed/i);
298
298
  });
299
299
  simulateRejectMessage("authorize/test_action");
300
300
  });
@@ -0,0 +1,58 @@
1
+ import { DelegationIdentity } from "@dfinity/identity";
2
+ import { OdinApiClient } from "./api";
3
+ import { AddLiquidityOptions, BuyOptions, CreateTokenParams, OdinCanisterClient, RemoveLiquidityOptions, SellOptions, SwapOptions, TransferOptions } from "./canister";
4
+ export declare class ConnectedUser {
5
+ private _identity;
6
+ private _api;
7
+ private _principal;
8
+ private _odin;
9
+ constructor(principal: string, identity: DelegationIdentity | null, api: OdinApiClient, odin: OdinCanisterClient);
10
+ getIdentity(): DelegationIdentity | null;
11
+ getUser(): Promise<import("..").OdinUser>;
12
+ getBalances(pagination: {
13
+ page: number;
14
+ limit: number;
15
+ }): Promise<readonly import("..").OdinBalance[]>;
16
+ getTokens(pagination: {
17
+ page: number;
18
+ limit: number;
19
+ }): Promise<{
20
+ data: {
21
+ balance: bigint;
22
+ token: import("..").OdinToken;
23
+ unrealized_pnl?: number;
24
+ unrealized_pnl_percent?: number;
25
+ }[];
26
+ count: number;
27
+ page: number;
28
+ limit: number;
29
+ }>;
30
+ getActivity(pagination: {
31
+ page: number;
32
+ limit: number;
33
+ }): Promise<import("./api").PaginatedResponse<import("..").OdinActivity>>;
34
+ getLiquidity(pagination: {
35
+ page: number;
36
+ limit: number;
37
+ }): Promise<{
38
+ data: {
39
+ balance: bigint;
40
+ token: import("..").OdinToken;
41
+ }[];
42
+ count: number;
43
+ page: number;
44
+ limit: number;
45
+ }>;
46
+ getAchievements(pagination: {
47
+ page: number;
48
+ limit: number;
49
+ }): Promise<readonly import("..").OdinAchievementCategory[]>;
50
+ sell(params: Omit<SellOptions, "principal">): Promise<boolean>;
51
+ buy(params: Omit<BuyOptions, "principal">): Promise<boolean>;
52
+ addLiquidity(params: Omit<AddLiquidityOptions, "principal">): Promise<boolean>;
53
+ removeLiquidity(params: Omit<RemoveLiquidityOptions, "principal">): Promise<boolean>;
54
+ transfer(params: Omit<TransferOptions, "principal">): Promise<boolean>;
55
+ createToken(params: Omit<CreateTokenParams, "principal">): Promise<boolean>;
56
+ swap(params: Omit<SwapOptions, "principal">): Promise<boolean>;
57
+ }
58
+ //# sourceMappingURL=connected-user.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connected-user.d.ts","sourceRoot":"","sources":["../../src/services/connected-user.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AACtC,OAAO,EACL,mBAAmB,EACnB,UAAU,EACV,iBAAiB,EACjB,kBAAkB,EAClB,sBAAsB,EACtB,WAAW,EACX,WAAW,EACX,eAAe,EAChB,MAAM,YAAY,CAAC;AAEpB,qBAAa,aAAa;IACxB,OAAO,CAAC,SAAS,CAA4B;IAC7C,OAAO,CAAC,IAAI,CAAgB;IAC5B,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,KAAK,CAAqB;gBAGhC,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,kBAAkB,GAAG,IAAI,EACnC,GAAG,EAAE,aAAa,EAClB,IAAI,EAAE,kBAAkB;IAQ1B,WAAW,IAAI,kBAAkB,GAAG,IAAI;IAIxC,OAAO;IAIP,WAAW,CAAC,UAAU,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE;IAIvD,SAAS,CAAC,UAAU,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE;;;;;;;;;;;IAIrD,WAAW,CAAC,UAAU,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE;IAIvD,YAAY,CAAC,UAAU,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE;;;;;;;;;IAIxD,eAAe,CAAC,UAAU,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE;IAM3D,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,WAAW,EAAE,WAAW,CAAC;IAO3C,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,UAAU,EAAE,WAAW,CAAC;IAOzC,YAAY,CAAC,MAAM,EAAE,IAAI,CAAC,mBAAmB,EAAE,WAAW,CAAC;IAO3D,eAAe,CAAC,MAAM,EAAE,IAAI,CAAC,sBAAsB,EAAE,WAAW,CAAC;IAOjE,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,eAAe,EAAE,WAAW,CAAC;IAOnD,WAAW,CAAC,MAAM,EAAE,IAAI,CAAC,iBAAiB,EAAE,WAAW,CAAC;IAOxD,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,WAAW,EAAE,WAAW,CAAC;CAM5C"}
@@ -0,0 +1,76 @@
1
+ export class ConnectedUser {
2
+ _identity;
3
+ _api;
4
+ _principal;
5
+ _odin;
6
+ constructor(principal, identity, api, odin) {
7
+ this._principal = principal;
8
+ this._identity = identity;
9
+ this._api = api;
10
+ this._odin = odin;
11
+ }
12
+ getIdentity() {
13
+ return this._identity;
14
+ }
15
+ getUser() {
16
+ return this._api.getUser(this._principal);
17
+ }
18
+ getBalances(pagination) {
19
+ return this._api.getBalances(this._principal, pagination);
20
+ }
21
+ getTokens(pagination) {
22
+ return this._api.getUserTokens(this._principal, pagination);
23
+ }
24
+ getActivity(pagination) {
25
+ return this._api.getUserActivity(this._principal, pagination);
26
+ }
27
+ getLiquidity(pagination) {
28
+ return this._api.getUserLiquidity(this._principal, pagination);
29
+ }
30
+ getAchievements(pagination) {
31
+ return this._api.getUserAchievements(this._principal, pagination);
32
+ }
33
+ /// others
34
+ sell(params) {
35
+ return this._odin.sell({
36
+ ...params,
37
+ principal: this._principal,
38
+ });
39
+ }
40
+ buy(params) {
41
+ return this._odin.buy({
42
+ ...params,
43
+ principal: this._principal,
44
+ });
45
+ }
46
+ addLiquidity(params) {
47
+ return this._odin.addLiquidity({
48
+ ...params,
49
+ principal: this._principal,
50
+ });
51
+ }
52
+ removeLiquidity(params) {
53
+ return this._odin.removeLiquidity({
54
+ ...params,
55
+ principal: this._principal,
56
+ });
57
+ }
58
+ transfer(params) {
59
+ return this._odin.transfer({
60
+ ...params,
61
+ principal: this._principal,
62
+ });
63
+ }
64
+ createToken(params) {
65
+ return this._odin.createToken({
66
+ ...params,
67
+ principal: this._principal,
68
+ });
69
+ }
70
+ swap(params) {
71
+ return this._odin.swap({
72
+ ...params,
73
+ principal: this._principal,
74
+ });
75
+ }
76
+ }
@@ -0,0 +1,12 @@
1
+ export interface WindowClientSettings {
2
+ target: string;
3
+ settings: string;
4
+ }
5
+ export declare class WindowClient {
6
+ private _settings;
7
+ constructor(options?: Partial<WindowClientSettings>);
8
+ get settings(): Partial<WindowClientSettings>;
9
+ set settings(settings: Partial<WindowClientSettings>);
10
+ open(url: URL): Window | null;
11
+ }
12
+ //# sourceMappingURL=window.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"window.d.ts","sourceRoot":"","sources":["../../src/services/window.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,qBAAa,YAAY;IACvB,OAAO,CAAC,SAAS,CAAuB;gBAE5B,OAAO,CAAC,EAAE,OAAO,CAAC,oBAAoB,CAAC;IAOnD,IAAI,QAAQ,IAIW,OAAO,CAAC,oBAAoB,CAAC,CAFnD;IAED,IAAI,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,oBAAoB,CAAC,EAKnD;IAED,IAAI,CAAC,GAAG,EAAE,GAAG;CAOd"}
@@ -0,0 +1,21 @@
1
+ export class WindowClient {
2
+ _settings;
3
+ constructor(options) {
4
+ this._settings = {
5
+ target: options?.target || "_blank",
6
+ settings: options?.settings || "",
7
+ };
8
+ }
9
+ get settings() {
10
+ return this._settings;
11
+ }
12
+ set settings(settings) {
13
+ this._settings = {
14
+ ...this._settings,
15
+ ...settings,
16
+ };
17
+ }
18
+ open(url) {
19
+ return window.open(url, this._settings?.target || "_blank", this._settings?.settings);
20
+ }
21
+ }
@@ -0,0 +1,2 @@
1
+ export declare function generateTid(length?: number): string;
2
+ //# sourceMappingURL=generate-tid.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate-tid.d.ts","sourceRoot":"","sources":["../../src/utils/generate-tid.ts"],"names":[],"mappings":"AAAA,wBAAgB,WAAW,CAAC,MAAM,GAAE,MAAU,UAS7C"}
@@ -0,0 +1,9 @@
1
+ export function generateTid(length = 8) {
2
+ const characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
3
+ let result = "";
4
+ const charactersLength = characters.length;
5
+ for (let i = 0; i < length; i++) {
6
+ result += characters.charAt(Math.floor(Math.random() * charactersLength));
7
+ }
8
+ return result;
9
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "odin-connect",
3
- "version": "1.1.3",
3
+ "version": "1.2.0",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
package/readme.md CHANGED
@@ -6,7 +6,7 @@
6
6
 
7
7
  ## Demo
8
8
 
9
- This repository includes a demo. See `demo/` folder
9
+ This repository includes a demo. See `/demo` folder
10
10
 
11
11
  To run it, simply do `npm run demo`
12
12
 
@@ -16,8 +16,11 @@ To run it, simply do `npm run demo`
16
16
 
17
17
  Instantiate the OdinConnect class with some information about your application
18
18
 
19
+ - `name` - Name of your app
20
+ - `env` - Odin Environment. Accepted values: `prod`, `dev`, `local`. Default: `prod`.
21
+
19
22
  ```typescript
20
- const odinConnect = new OdinConnect({ name: "Demo App" });
23
+ const odinConnect = new OdinConnect({ name: "Demo App", env: "prod" });
21
24
  ```
22
25
 
23
26
  ### Request for user connection
@@ -48,13 +51,18 @@ const user = await odinConnect.connect({
48
51
  const identity = user.getIdentity();
49
52
  ```
50
53
 
51
- ### Request for user balances
54
+ ### Request for various user data from API
52
55
 
53
56
  ```typescript
54
- const balances = await odinConnect.getBalances({
55
- principal: "veyov-kjgrf-hke6v-6d63i-sdwae-oldgg-huau6-ke5g3-rllp2-5jhca-uqe",
56
- pagination: { page: 1, limit: 20 },
57
- });
57
+ const user = await odinConnect.connect();
58
+ // get tokens
59
+ const tokens = await user.getTokens({ page: 1, limit: 10 });
60
+ // get liquidity
61
+ const liquidity = await user.getLiquidity({ page: 1, limit: 10 });
62
+ // get activity
63
+ const activity = await user.getActivity({ page: 1, limit: 10 });
64
+ // get achievements
65
+ const achievements = await user.getAchievements({ page: 1, limit: 10 });
58
66
  ```
59
67
 
60
68
  ### Request for token transfer
@@ -72,49 +80,50 @@ await odinConnect.transfer({
72
80
  ### Request for buy authorization
73
81
 
74
82
  ```typescript
75
- await odinConnect.buy({
76
- btcAmount: 20_000_000n,
83
+ const user = await odinConnect.connect();
84
+ await user.buy({
85
+ btcAmount: 10_000_000n,
77
86
  token: "2jjj",
78
- principal: "veyov-kjgrf-hke6v-6d63i-sdwae-oldgg-huau6-ke5g3-rllp2-5jhca-uqe",
79
87
  });
80
88
  ```
81
89
 
82
90
  ### Request for sell authorization
83
91
 
84
92
  ```typescript
85
- await odinConnect.sell({
93
+ const user = await odinConnect.connect();
94
+ await user.sell({
86
95
  tokenAmount: 20_000_000n,
87
96
  token: "2jjj",
88
- principal: "veyov-kjgrf-hke6v-6d63i-sdwae-oldgg-huau6-ke5g3-rllp2-5jhca-uqe",
89
97
  });
90
98
  ```
91
99
 
92
100
  ### Request for add liquidity authorization
93
101
 
94
102
  ```typescript
95
- await odinConnect.addLiquidity({
103
+ const user = await odinConnect.connect();
104
+ await user.addLiquidity({
96
105
  btcAmount: 20_000_000n,
97
106
  token: "2jj",
98
- principal: "veyov-kjgrf-hke6v-6d63i-sdwae-oldgg-huau6-ke5g3-rllp2-5jhca-uqe",
99
107
  });
100
108
  ```
101
109
 
102
110
  ### Request for remove liquidity authorization
103
111
 
104
112
  ```typescript
105
- await odinConnect.removeLiquidity({
113
+ const user = await odinConnect.connect();
114
+ await user.removeLiquidity({
106
115
  btcAmount: 20_000_000n,
107
116
  token: "2jj",
108
- principal: "veyov-kjgrf-hke6v-6d63i-sdwae-oldgg-huau6-ke5g3-rllp2-5jhca-uqe",
109
117
  });
110
118
  ```
111
119
 
112
120
  ### Request for creating new token
113
121
 
114
- Note: require_api must be set set to true
122
+ Note: `require_api` must be set set to true
115
123
 
116
124
  ```typescript
117
- await odinConnect.createToken({
125
+ const user = await odinConnect.connect({ requires_api: true });
126
+ await user.createToken({
118
127
  image: file, // instance of a file
119
128
  principal: "veyov-kjgrf-hke6v-6d63i-sdwae-oldgg-huau6-ke5g3-rllp2-5jhca-uqe",
120
129
  name: "Test Token",
@@ -132,33 +141,37 @@ await odinConnect.createToken({
132
141
 
133
142
  ```typescript
134
143
  // Get tokens
135
- const tokens = await odinConnect.getTokens({
144
+ const tokens = await odinConnect.api.getTokens({
136
145
  pagination: { page: 1, limit: 50 },
137
146
  sort: { field: "marketcap", direction: "desc" },
138
147
  });
139
148
 
140
- // Get token info
141
- const token = await odinConnect.getToken("2jjj");
149
+ // Get activities
150
+ const activity = await odinConnect.api.getUserActivity({
151
+ pagination: { page: 1, limit: 10 },
152
+ });
153
+
154
+ // Get token by id
155
+ const token = await odinConnect.api.getToken("2jjj");
142
156
 
143
- // Get user info
144
- const user = await odinConnect.getUser(
157
+ // Get user data by id
158
+ const user = await odinConnect.api.getUser(
145
159
  "veyov-kjgrf-hke6v-6d63i-sdwae-oldgg-huau6-ke5g3-rllp2-5jhca-uqe"
146
160
  );
147
161
 
148
- // Get user balance
149
- const balances = await odinConnect.getBalances({
150
- principal: user.principal,
162
+ // Get user balance by user id
163
+ const balances = await odinConnect.api.getBalances({
164
+ principal: "veyov-kjgrf-hke6v-6d63i-sdwae-oldgg-huau6-ke5g3-rllp2-5jhca-uqe",
151
165
  pagination: { page: 1, limit: 20 },
152
166
  });
153
167
 
154
- // Get user activities
155
- const activity = await odinConnect.getUserActivity({
168
+ // Get activities by user id
169
+ const activity = await odinConnect.api.getUserActivity({
156
170
  principal: "veyov-kjgrf-hke6v-6d63i-sdwae-oldgg-huau6-ke5g3-rllp2-5jhca-uqe",
157
171
  pagination: { page: 1, limit: 10 },
158
172
  });
159
173
  ```
160
174
 
161
- ### Notes
175
+ ## General Notes
162
176
 
163
- - The `principal` sent should match the currently logged in user in ODIN.
164
177
  - BTC amounts are in millisatoshis