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.
- package/demo/package-lock.json +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/services/api.d.ts +1 -1
- package/dist/services/api.d.ts.map +1 -1
- package/dist/services/api.js +1 -1
- package/dist/services/api.test.js +5 -7
- package/dist/services/canister.d.ts +65 -0
- package/dist/services/canister.d.ts.map +1 -0
- package/dist/services/canister.js +191 -0
- package/dist/services/connect-user.d.ts +9 -2
- package/dist/services/connect-user.d.ts.map +1 -1
- package/dist/services/connect-user.js +34 -1
- package/dist/services/connect.d.ts +12 -71
- package/dist/services/connect.d.ts.map +1 -1
- package/dist/services/connect.js +25 -187
- package/dist/services/connect.test.js +15 -15
- package/dist/services/connected-user.d.ts +58 -0
- package/dist/services/connected-user.d.ts.map +1 -0
- package/dist/services/connected-user.js +76 -0
- package/dist/services/window.d.ts +12 -0
- package/dist/services/window.d.ts.map +1 -0
- package/dist/services/window.js +21 -0
- package/dist/utils/generate-tid.d.ts +2 -0
- package/dist/utils/generate-tid.d.ts.map +1 -0
- package/dist/utils/generate-tid.js +9 -0
- package/package.json +1 -1
- package/readme.md +43 -30
package/demo/package-lock.json
CHANGED
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
|
package/dist/index.d.ts.map
CHANGED
|
@@ -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"}
|
package/dist/services/api.d.ts
CHANGED
|
@@ -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,
|
|
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"}
|
package/dist/services/api.js
CHANGED
|
@@ -1,20 +1,18 @@
|
|
|
1
1
|
import { beforeAll, describe, expect, it, vi } from "vitest";
|
|
2
|
-
import {
|
|
2
|
+
import { OdinApiClient } from "./api";
|
|
3
3
|
describe("ApiClient", () => {
|
|
4
4
|
let api;
|
|
5
5
|
beforeAll(() => {
|
|
6
|
-
api = new
|
|
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
|
|
11
|
-
expect(api).toBeInstanceOf(
|
|
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
|
|
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 {
|
|
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
|
-
|
|
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,
|
|
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
|
-
|
|
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 {
|
|
2
|
-
import { ConnectedUser } from "./
|
|
1
|
+
import { OdinApiClient } from "./api";
|
|
2
|
+
import { ConnectedUser } from "./connected-user";
|
|
3
3
|
import { Environment } from "../models/environment";
|
|
4
|
-
|
|
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
|
|
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
|
-
|
|
86
|
-
|
|
87
|
-
get
|
|
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":"
|
|
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"}
|
package/dist/services/connect.js
CHANGED
|
@@ -1,23 +1,23 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { createTokenValidators } from "../utils";
|
|
1
|
+
import { OdinApiClient } from "./api";
|
|
3
2
|
import { DelegationChain, DelegationIdentity, Ed25519KeyIdentity, } from "@dfinity/identity";
|
|
4
|
-
import { ConnectedUser } from "./
|
|
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
|
-
|
|
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
|
|
17
|
-
this.
|
|
18
|
-
|
|
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
|
-
|
|
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.
|
|
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.
|
|
65
|
+
connectedUser = new ConnectedUser(principal, identity, this.api, this._odin);
|
|
63
66
|
}
|
|
64
67
|
else {
|
|
65
|
-
connectedUser = new ConnectedUser(principal, null, this.
|
|
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
|
|
87
|
+
url.searchParams.append("targets", targets?.join(",") || "");
|
|
85
88
|
}
|
|
86
|
-
this.
|
|
89
|
+
this._window.open(url);
|
|
87
90
|
window.addEventListener("message", handleMessage);
|
|
88
91
|
});
|
|
89
92
|
}
|
|
90
|
-
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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).
|
|
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 @@
|
|
|
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
package/readme.md
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
## Demo
|
|
8
8
|
|
|
9
|
-
This repository includes a demo. See `
|
|
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
|
|
54
|
+
### Request for various user data from API
|
|
52
55
|
|
|
53
56
|
```typescript
|
|
54
|
-
const
|
|
55
|
-
|
|
56
|
-
|
|
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.
|
|
76
|
-
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
|
141
|
-
const
|
|
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
|
|
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:
|
|
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
|
|
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
|
-
|
|
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
|