@ledgerhq/ledger-trust-service 0.1.0-next.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/.eslintrc.js +20 -0
- package/.turbo/turbo-build.log +4 -0
- package/CHANGELOG.md +7 -0
- package/LICENSE.txt +21 -0
- package/jest.config.js +8 -0
- package/jest.integ.config.js +8 -0
- package/lib/common.d.ts +2 -0
- package/lib/common.d.ts.map +1 -0
- package/lib/common.js +11 -0
- package/lib/common.js.map +1 -0
- package/lib/index.d.ts +6 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +12 -0
- package/lib/index.js.map +1 -0
- package/lib/solana.d.ts +9 -0
- package/lib/solana.d.ts.map +1 -0
- package/lib/solana.integ.test.d.ts +2 -0
- package/lib/solana.integ.test.d.ts.map +1 -0
- package/lib/solana.integ.test.js +37 -0
- package/lib/solana.integ.test.js.map +1 -0
- package/lib/solana.js +48 -0
- package/lib/solana.js.map +1 -0
- package/lib/solana.test.d.ts +2 -0
- package/lib/solana.test.d.ts.map +1 -0
- package/lib/solana.test.js +115 -0
- package/lib/solana.test.js.map +1 -0
- package/lib-es/common.d.ts +2 -0
- package/lib-es/common.d.ts.map +1 -0
- package/lib-es/common.js +7 -0
- package/lib-es/common.js.map +1 -0
- package/lib-es/index.d.ts +6 -0
- package/lib-es/index.d.ts.map +1 -0
- package/lib-es/index.js +10 -0
- package/lib-es/index.js.map +1 -0
- package/lib-es/solana.d.ts +9 -0
- package/lib-es/solana.d.ts.map +1 -0
- package/lib-es/solana.integ.test.d.ts +2 -0
- package/lib-es/solana.integ.test.d.ts.map +1 -0
- package/lib-es/solana.integ.test.js +35 -0
- package/lib-es/solana.integ.test.js.map +1 -0
- package/lib-es/solana.js +40 -0
- package/lib-es/solana.js.map +1 -0
- package/lib-es/solana.test.d.ts +2 -0
- package/lib-es/solana.test.d.ts.map +1 -0
- package/lib-es/solana.test.js +110 -0
- package/lib-es/solana.test.js.map +1 -0
- package/package.json +85 -0
- package/src/common.ts +7 -0
- package/src/index.ts +11 -0
- package/src/solana.integ.test.ts +42 -0
- package/src/solana.test.ts +114 -0
- package/src/solana.ts +55 -0
- package/tsconfig.json +12 -0
package/.eslintrc.js
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
module.exports = {
|
|
2
|
+
env: {
|
|
3
|
+
browser: true,
|
|
4
|
+
es6: true,
|
|
5
|
+
},
|
|
6
|
+
overrides: [
|
|
7
|
+
{
|
|
8
|
+
files: ["src/**/*.test.ts"],
|
|
9
|
+
env: {
|
|
10
|
+
"jest/globals": true,
|
|
11
|
+
},
|
|
12
|
+
plugins: ["jest"],
|
|
13
|
+
},
|
|
14
|
+
],
|
|
15
|
+
rules: {
|
|
16
|
+
"no-console": ["error", { allow: ["warn", "error"] }],
|
|
17
|
+
"@typescript-eslint/no-empty-function": "off",
|
|
18
|
+
"@typescript-eslint/no-explicit-any": "warn",
|
|
19
|
+
},
|
|
20
|
+
};
|
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
# @ledgerhq/ledger-trust-service
|
|
2
|
+
|
|
3
|
+
## 0.1.0-next.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#8517](https://github.com/LedgerHQ/ledger-live/pull/8517) [`2673c1d`](https://github.com/LedgerHQ/ledger-live/commit/2673c1d98788fafe7e95bd798be06a6b5e39e1c0) Thanks [@sprohaszka-ledger](https://github.com/sprohaszka-ledger)! - Extract Ledger services (CAL and Trust) calls and expose new BOLOS APDU
|
package/LICENSE.txt
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
The MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2017-present Ledger https://www.ledger.com/
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
|
13
|
+
all copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
21
|
+
THE SOFTWARE.
|
package/jest.config.js
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/** @type {import('ts-jest/dist/types').JestConfigWithTsJest} */
|
|
2
|
+
// `workerThreads: true` is required for validating object with `bigint` values
|
|
3
|
+
module.exports = {
|
|
4
|
+
preset: "ts-jest",
|
|
5
|
+
testEnvironment: "node",
|
|
6
|
+
testPathIgnorePatterns: ["lib/", "lib-es/", ".*\\.integ\\.test\\.[tj]s"],
|
|
7
|
+
workerThreads: true,
|
|
8
|
+
};
|
package/lib/common.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"common.d.ts","sourceRoot":"","sources":["../src/common.ts"],"names":[],"mappings":"AAEA,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAI7D"}
|
package/lib/common.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getTrustedDomain = void 0;
|
|
4
|
+
const live_env_1 = require("@ledgerhq/live-env");
|
|
5
|
+
function getTrustedDomain(env) {
|
|
6
|
+
return env === "prod"
|
|
7
|
+
? (0, live_env_1.getEnv)("NFT_ETH_METADATA_SERVICE")
|
|
8
|
+
: "https://nft.api.live.ledger-stg.com";
|
|
9
|
+
}
|
|
10
|
+
exports.getTrustedDomain = getTrustedDomain;
|
|
11
|
+
//# sourceMappingURL=common.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"common.js","sourceRoot":"","sources":["../src/common.ts"],"names":[],"mappings":";;;AAAA,iDAA4C;AAE5C,SAAgB,gBAAgB,CAAC,GAAoB;IACnD,OAAO,GAAG,KAAK,MAAM;QACnB,CAAC,CAAC,IAAA,iBAAM,EAAC,0BAA0B,CAAC;QACpC,CAAC,CAAC,qCAAqC,CAAC;AAC5C,CAAC;AAJD,4CAIC"}
|
package/lib/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;;;;AAE3C,wBAEE"}
|
package/lib/index.js
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*
|
|
3
|
+
* Trust Service
|
|
4
|
+
*
|
|
5
|
+
* Use only exposed methods below outside of this module.
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
const solana_1 = require("./solana");
|
|
9
|
+
exports.default = {
|
|
10
|
+
getOwnerAddress: solana_1.getOwnerAddress,
|
|
11
|
+
};
|
|
12
|
+
//# sourceMappingURL=index.js.map
|
package/lib/index.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;AAEH,qCAA2C;AAE3C,kBAAe;IACb,eAAe,EAAf,wBAAe;CAChB,CAAC"}
|
package/lib/solana.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export type OwnerInfo = {
|
|
2
|
+
tokenAccount: string;
|
|
3
|
+
owner: string;
|
|
4
|
+
contract: string;
|
|
5
|
+
signedDescriptor: string;
|
|
6
|
+
};
|
|
7
|
+
export declare function getOwnerAddress(tokenAddress: string, challenge: string, env?: "prod" | "test"): Promise<OwnerInfo>;
|
|
8
|
+
export declare function computedTokenAddress(address: string, mintAddress: string, challenge: string, env?: "prod" | "test"): Promise<OwnerInfo>;
|
|
9
|
+
//# sourceMappingURL=solana.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"solana.d.ts","sourceRoot":"","sources":["../src/solana.ts"],"names":[],"mappings":"AAYA,MAAM,MAAM,SAAS,GAAG;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,gBAAgB,EAAE,MAAM,CAAC;CAC1B,CAAC;AAEF,wBAAsB,eAAe,CACnC,YAAY,EAAE,MAAM,EACpB,SAAS,EAAE,MAAM,EACjB,GAAG,GAAE,MAAM,GAAG,MAAe,GAC5B,OAAO,CAAC,SAAS,CAAC,CAYpB;AAED,wBAAsB,oBAAoB,CACxC,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EACjB,GAAG,GAAE,MAAM,GAAG,MAAe,GAC5B,OAAO,CAAC,SAAS,CAAC,CAYpB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"solana.integ.test.d.ts","sourceRoot":"","sources":["../src/solana.integ.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
const solana_1 = require("./solana");
|
|
13
|
+
describe("getOwnerAddress", () => {
|
|
14
|
+
it("returns expected ATA info", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
15
|
+
// When
|
|
16
|
+
const result = yield (0, solana_1.getOwnerAddress)("EQ96zptNAWwM23m5v2ByChCMTFu6zUmJgRtUrQV1uYNM", "", "test");
|
|
17
|
+
// Then
|
|
18
|
+
expect(result).toEqual(expect.objectContaining({
|
|
19
|
+
tokenAccount: "EQ96zptNAWwM23m5v2ByChCMTFu6zUmJgRtUrQV1uYNM",
|
|
20
|
+
owner: "AS1kiySqqS6Tvv3KmBsr8Zbg4DUo5fDxDD9v1dF1TVYr",
|
|
21
|
+
contract: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
|
|
22
|
+
}));
|
|
23
|
+
}));
|
|
24
|
+
});
|
|
25
|
+
describe("computedTokenAddress", () => {
|
|
26
|
+
it("returns expected ATA info", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
27
|
+
// When
|
|
28
|
+
const result = yield (0, solana_1.computedTokenAddress)("DHTPaexpcpK58w4UpvoLnFH55jfwJdpg4R73mUwryZU8", "4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU", "", "test");
|
|
29
|
+
// Then
|
|
30
|
+
expect(result).toEqual(expect.objectContaining({
|
|
31
|
+
tokenAccount: "GizbHjLkKspW5XzkUsWKSoWW3VwBJMYi39NwCmppsbRs",
|
|
32
|
+
owner: "DHTPaexpcpK58w4UpvoLnFH55jfwJdpg4R73mUwryZU8",
|
|
33
|
+
contract: "4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU",
|
|
34
|
+
}));
|
|
35
|
+
}));
|
|
36
|
+
});
|
|
37
|
+
//# sourceMappingURL=solana.integ.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"solana.integ.test.js","sourceRoot":"","sources":["../src/solana.integ.test.ts"],"names":[],"mappings":";;;;;;;;;;;AAAA,qCAAiE;AAEjE,QAAQ,CAAC,iBAAiB,EAAE,GAAG,EAAE;IAC/B,EAAE,CAAC,2BAA2B,EAAE,GAAS,EAAE;QACzC,OAAO;QACP,MAAM,MAAM,GAAG,MAAM,IAAA,wBAAe,EAClC,8CAA8C,EAC9C,EAAE,EACF,MAAM,CACP,CAAC;QAEF,OAAO;QACP,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CACpB,MAAM,CAAC,gBAAgB,CAAC;YACtB,YAAY,EAAE,8CAA8C;YAC5D,KAAK,EAAE,8CAA8C;YACrD,QAAQ,EAAE,8CAA8C;SACzD,CAAC,CACH,CAAC;IACJ,CAAC,CAAA,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,sBAAsB,EAAE,GAAG,EAAE;IACpC,EAAE,CAAC,2BAA2B,EAAE,GAAS,EAAE;QACzC,OAAO;QACP,MAAM,MAAM,GAAG,MAAM,IAAA,6BAAoB,EACvC,8CAA8C,EAC9C,8CAA8C,EAC9C,EAAE,EACF,MAAM,CACP,CAAC;QAEF,OAAO;QACP,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CACpB,MAAM,CAAC,gBAAgB,CAAC;YACtB,YAAY,EAAE,8CAA8C;YAC5D,KAAK,EAAE,8CAA8C;YACrD,QAAQ,EAAE,8CAA8C;SACzD,CAAC,CACH,CAAC;IACJ,CAAC,CAAA,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
package/lib/solana.js
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.computedTokenAddress = exports.getOwnerAddress = void 0;
|
|
16
|
+
const live_network_1 = __importDefault(require("@ledgerhq/live-network"));
|
|
17
|
+
const common_1 = require("./common");
|
|
18
|
+
function getOwnerAddress(tokenAddress_1, challenge_1) {
|
|
19
|
+
return __awaiter(this, arguments, void 0, function* (tokenAddress, challenge, env = "prod") {
|
|
20
|
+
const { data } = yield (0, live_network_1.default)({
|
|
21
|
+
method: "GET",
|
|
22
|
+
url: `${(0, common_1.getTrustedDomain)(env)}/v2/solana/owner/${tokenAddress}?challenge=${challenge}`,
|
|
23
|
+
});
|
|
24
|
+
return {
|
|
25
|
+
tokenAccount: data.tokenAccount,
|
|
26
|
+
owner: data.owner,
|
|
27
|
+
contract: data.contract,
|
|
28
|
+
signedDescriptor: data.signedDescriptor,
|
|
29
|
+
};
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
exports.getOwnerAddress = getOwnerAddress;
|
|
33
|
+
function computedTokenAddress(address_1, mintAddress_1, challenge_1) {
|
|
34
|
+
return __awaiter(this, arguments, void 0, function* (address, mintAddress, challenge, env = "prod") {
|
|
35
|
+
const { data } = yield (0, live_network_1.default)({
|
|
36
|
+
method: "GET",
|
|
37
|
+
url: `${(0, common_1.getTrustedDomain)(env)}/v2/solana/computed-token-account/${address}/${mintAddress}?challenge=${challenge}`,
|
|
38
|
+
});
|
|
39
|
+
return {
|
|
40
|
+
tokenAccount: data.tokenAccount,
|
|
41
|
+
owner: data.owner,
|
|
42
|
+
contract: data.contract,
|
|
43
|
+
signedDescriptor: data.signedDescriptor,
|
|
44
|
+
};
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
exports.computedTokenAddress = computedTokenAddress;
|
|
48
|
+
//# sourceMappingURL=solana.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"solana.js","sourceRoot":"","sources":["../src/solana.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,0EAA6C;AAC7C,qCAA4C;AAkB5C,SAAsB,eAAe;yDACnC,YAAoB,EACpB,SAAiB,EACjB,MAAuB,MAAM;QAE7B,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,IAAA,sBAAO,EAAuB;YACnD,MAAM,EAAE,KAAK;YACb,GAAG,EAAE,GAAG,IAAA,yBAAgB,EAAC,GAAG,CAAC,oBAAoB,YAAY,cAAc,SAAS,EAAE;SACvF,CAAC,CAAC;QAEH,OAAO;YACL,YAAY,EAAE,IAAI,CAAC,YAAY;YAC/B,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,gBAAgB,EAAE,IAAI,CAAC,gBAAgB;SACxC,CAAC;IACJ,CAAC;CAAA;AAhBD,0CAgBC;AAED,SAAsB,oBAAoB;yDACxC,OAAe,EACf,WAAmB,EACnB,SAAiB,EACjB,MAAuB,MAAM;QAE7B,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,IAAA,sBAAO,EAAuB;YACnD,MAAM,EAAE,KAAK;YACb,GAAG,EAAE,GAAG,IAAA,yBAAgB,EAAC,GAAG,CAAC,qCAAqC,OAAO,IAAI,WAAW,cAAc,SAAS,EAAE;SAClH,CAAC,CAAC;QAEH,OAAO;YACL,YAAY,EAAE,IAAI,CAAC,YAAY;YAC/B,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,gBAAgB,EAAE,IAAI,CAAC,gBAAgB;SACxC,CAAC;IACJ,CAAC;CAAA;AAjBD,oDAiBC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"solana.test.d.ts","sourceRoot":"","sources":["../src/solana.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
const solana_1 = require("./solana");
|
|
16
|
+
const live_network_1 = __importDefault(require("@ledgerhq/live-network"));
|
|
17
|
+
jest.mock("@ledgerhq/live-network");
|
|
18
|
+
describe("solana", () => {
|
|
19
|
+
beforeEach(() => {
|
|
20
|
+
jest.resetModules();
|
|
21
|
+
jest.clearAllMocks();
|
|
22
|
+
});
|
|
23
|
+
describe("getOwnerAddress", () => {
|
|
24
|
+
it.each([
|
|
25
|
+
["prod", "https://nft.api.live.ledger.com"],
|
|
26
|
+
[undefined, "https://nft.api.live.ledger.com"],
|
|
27
|
+
["test", "https://nft.api.live.ledger-stg.com"],
|
|
28
|
+
])("fetch the correct %s service environement", (env, baseUrl) => __awaiter(void 0, void 0, void 0, function* () {
|
|
29
|
+
// Given
|
|
30
|
+
const ownerAddress = "SOL_ADDR";
|
|
31
|
+
const challenge = "WHATEVER_CHALLENGE";
|
|
32
|
+
const mockResponse = {};
|
|
33
|
+
live_network_1.default.mockResolvedValue({ data: mockResponse });
|
|
34
|
+
// When
|
|
35
|
+
yield (0, solana_1.getOwnerAddress)(ownerAddress, challenge, env);
|
|
36
|
+
// Then
|
|
37
|
+
expect(live_network_1.default).toHaveBeenCalledWith({
|
|
38
|
+
method: "GET",
|
|
39
|
+
url: `${baseUrl}/v2/solana/owner/${ownerAddress}?challenge=${challenge}`,
|
|
40
|
+
});
|
|
41
|
+
}));
|
|
42
|
+
it("transforms data as expected", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
43
|
+
// Given
|
|
44
|
+
const ownerAddress = "SOL_ADDR";
|
|
45
|
+
const challenge = "WHATEVER_CHALLENGE";
|
|
46
|
+
const mintAddress = "MINT_ADDR";
|
|
47
|
+
const tokenAddress = "TOKEN_ADDR";
|
|
48
|
+
const mockResponse = {
|
|
49
|
+
descriptorType: "TrustedName",
|
|
50
|
+
descriptorVersion: 2,
|
|
51
|
+
tokenAccount: tokenAddress,
|
|
52
|
+
owner: ownerAddress,
|
|
53
|
+
contract: mintAddress,
|
|
54
|
+
signedDescriptor: "SIGNATURE",
|
|
55
|
+
};
|
|
56
|
+
live_network_1.default.mockResolvedValue({ data: mockResponse });
|
|
57
|
+
// When
|
|
58
|
+
const result = yield (0, solana_1.getOwnerAddress)(ownerAddress, challenge);
|
|
59
|
+
// Then
|
|
60
|
+
expect(result).toEqual({
|
|
61
|
+
contract: mintAddress,
|
|
62
|
+
owner: ownerAddress,
|
|
63
|
+
tokenAccount: tokenAddress,
|
|
64
|
+
signedDescriptor: "SIGNATURE",
|
|
65
|
+
});
|
|
66
|
+
}));
|
|
67
|
+
});
|
|
68
|
+
describe("computedTokenAddress", () => {
|
|
69
|
+
it.each([
|
|
70
|
+
["prod", "https://nft.api.live.ledger.com"],
|
|
71
|
+
[undefined, "https://nft.api.live.ledger.com"],
|
|
72
|
+
["test", "https://nft.api.live.ledger-stg.com"],
|
|
73
|
+
])("fetch the correct %s service environement", (env, baseUrl) => __awaiter(void 0, void 0, void 0, function* () {
|
|
74
|
+
// Given
|
|
75
|
+
const ownerAddress = "SOL_ADDR";
|
|
76
|
+
const mintAddress = "MINT_ADDR";
|
|
77
|
+
const challenge = "WHATEVER_CHALLENGE";
|
|
78
|
+
const mockResponse = {};
|
|
79
|
+
live_network_1.default.mockResolvedValue({ data: mockResponse });
|
|
80
|
+
// When
|
|
81
|
+
yield (0, solana_1.computedTokenAddress)(ownerAddress, mintAddress, challenge, env);
|
|
82
|
+
// Then
|
|
83
|
+
expect(live_network_1.default).toHaveBeenCalledWith({
|
|
84
|
+
method: "GET",
|
|
85
|
+
url: `${baseUrl}/v2/solana/computed-token-account/${ownerAddress}/${mintAddress}?challenge=${challenge}`,
|
|
86
|
+
});
|
|
87
|
+
}));
|
|
88
|
+
it("transforms data as expected", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
89
|
+
// Given
|
|
90
|
+
const ownerAddress = "SOL_ADDR";
|
|
91
|
+
const challenge = "WHATEVER_CHALLENGE";
|
|
92
|
+
const mintAddress = "MINT_ADDR";
|
|
93
|
+
const tokenAddress = "TOKEN_ADDR";
|
|
94
|
+
const mockResponse = {
|
|
95
|
+
descriptorType: "TrustedName",
|
|
96
|
+
descriptorVersion: 2,
|
|
97
|
+
tokenAccount: tokenAddress,
|
|
98
|
+
owner: ownerAddress,
|
|
99
|
+
contract: mintAddress,
|
|
100
|
+
signedDescriptor: "SIGNATURE",
|
|
101
|
+
};
|
|
102
|
+
live_network_1.default.mockResolvedValue({ data: mockResponse });
|
|
103
|
+
// When
|
|
104
|
+
const result = yield (0, solana_1.computedTokenAddress)(ownerAddress, mintAddress, challenge);
|
|
105
|
+
// Then
|
|
106
|
+
expect(result).toEqual({
|
|
107
|
+
contract: mintAddress,
|
|
108
|
+
owner: ownerAddress,
|
|
109
|
+
tokenAccount: tokenAddress,
|
|
110
|
+
signedDescriptor: "SIGNATURE",
|
|
111
|
+
});
|
|
112
|
+
}));
|
|
113
|
+
});
|
|
114
|
+
});
|
|
115
|
+
//# sourceMappingURL=solana.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"solana.test.js","sourceRoot":"","sources":["../src/solana.test.ts"],"names":[],"mappings":";;;;;;;;;;;;;;AAAA,qCAAiE;AACjE,0EAA6C;AAE7C,IAAI,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC;AAEpC,QAAQ,CAAC,QAAQ,EAAE,GAAG,EAAE;IACtB,UAAU,CAAC,GAAG,EAAE;QACd,IAAI,CAAC,YAAY,EAAE,CAAC;QACpB,IAAI,CAAC,aAAa,EAAE,CAAC;IACvB,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,iBAAiB,EAAE,GAAG,EAAE;QAC/B,EAAE,CAAC,IAAI,CAAC;YACN,CAAC,MAAM,EAAE,iCAAiC,CAAC;YAC3C,CAAC,SAAS,EAAE,iCAAiC,CAAC;YAC9C,CAAC,MAAM,EAAE,qCAAqC,CAAC;SAChD,CAAC,CAAC,2CAA2C,EAAE,CAAO,GAAG,EAAE,OAAO,EAAE,EAAE;YACrE,QAAQ;YACR,MAAM,YAAY,GAAG,UAAU,CAAC;YAChC,MAAM,SAAS,GAAG,oBAAoB,CAAC;YACvC,MAAM,YAAY,GAAG,EAAE,CAAC;YACvB,sBAAqB,CAAC,iBAAiB,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC,CAAC;YAEjE,OAAO;YACP,MAAM,IAAA,wBAAe,EAAC,YAAY,EAAE,SAAS,EAAE,GAAsB,CAAC,CAAC;YAEvE,OAAO;YACP,MAAM,CAAC,sBAAO,CAAC,CAAC,oBAAoB,CAAC;gBACnC,MAAM,EAAE,KAAK;gBACb,GAAG,EAAE,GAAG,OAAO,oBAAoB,YAAY,cAAc,SAAS,EAAE;aACzE,CAAC,CAAC;QACL,CAAC,CAAA,CAAC,CAAC;QAEH,EAAE,CAAC,6BAA6B,EAAE,GAAS,EAAE;YAC3C,QAAQ;YACR,MAAM,YAAY,GAAG,UAAU,CAAC;YAChC,MAAM,SAAS,GAAG,oBAAoB,CAAC;YACvC,MAAM,WAAW,GAAG,WAAW,CAAC;YAChC,MAAM,YAAY,GAAG,YAAY,CAAC;YAClC,MAAM,YAAY,GAAG;gBACnB,cAAc,EAAE,aAAa;gBAC7B,iBAAiB,EAAE,CAAC;gBACpB,YAAY,EAAE,YAAY;gBAC1B,KAAK,EAAE,YAAY;gBACnB,QAAQ,EAAE,WAAW;gBACrB,gBAAgB,EAAE,WAAW;aAC9B,CAAC;YACD,sBAAqB,CAAC,iBAAiB,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC,CAAC;YAEjE,OAAO;YACP,MAAM,MAAM,GAAG,MAAM,IAAA,wBAAe,EAAC,YAAY,EAAE,SAAS,CAAC,CAAC;YAE9D,OAAO;YACP,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC;gBACrB,QAAQ,EAAE,WAAW;gBACrB,KAAK,EAAE,YAAY;gBACnB,YAAY,EAAE,YAAY;gBAC1B,gBAAgB,EAAE,WAAW;aAC9B,CAAC,CAAC;QACL,CAAC,CAAA,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,sBAAsB,EAAE,GAAG,EAAE;QACpC,EAAE,CAAC,IAAI,CAAC;YACN,CAAC,MAAM,EAAE,iCAAiC,CAAC;YAC3C,CAAC,SAAS,EAAE,iCAAiC,CAAC;YAC9C,CAAC,MAAM,EAAE,qCAAqC,CAAC;SAChD,CAAC,CAAC,2CAA2C,EAAE,CAAO,GAAG,EAAE,OAAO,EAAE,EAAE;YACrE,QAAQ;YACR,MAAM,YAAY,GAAG,UAAU,CAAC;YAChC,MAAM,WAAW,GAAG,WAAW,CAAC;YAChC,MAAM,SAAS,GAAG,oBAAoB,CAAC;YACvC,MAAM,YAAY,GAAG,EAAE,CAAC;YACvB,sBAAqB,CAAC,iBAAiB,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC,CAAC;YAEjE,OAAO;YACP,MAAM,IAAA,6BAAoB,EAAC,YAAY,EAAE,WAAW,EAAE,SAAS,EAAE,GAAsB,CAAC,CAAC;YAEzF,OAAO;YACP,MAAM,CAAC,sBAAO,CAAC,CAAC,oBAAoB,CAAC;gBACnC,MAAM,EAAE,KAAK;gBACb,GAAG,EAAE,GAAG,OAAO,qCAAqC,YAAY,IAAI,WAAW,cAAc,SAAS,EAAE;aACzG,CAAC,CAAC;QACL,CAAC,CAAA,CAAC,CAAC;QAEH,EAAE,CAAC,6BAA6B,EAAE,GAAS,EAAE;YAC3C,QAAQ;YACR,MAAM,YAAY,GAAG,UAAU,CAAC;YAChC,MAAM,SAAS,GAAG,oBAAoB,CAAC;YACvC,MAAM,WAAW,GAAG,WAAW,CAAC;YAChC,MAAM,YAAY,GAAG,YAAY,CAAC;YAClC,MAAM,YAAY,GAAG;gBACnB,cAAc,EAAE,aAAa;gBAC7B,iBAAiB,EAAE,CAAC;gBACpB,YAAY,EAAE,YAAY;gBAC1B,KAAK,EAAE,YAAY;gBACnB,QAAQ,EAAE,WAAW;gBACrB,gBAAgB,EAAE,WAAW;aAC9B,CAAC;YACD,sBAAqB,CAAC,iBAAiB,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC,CAAC;YAEjE,OAAO;YACP,MAAM,MAAM,GAAG,MAAM,IAAA,6BAAoB,EAAC,YAAY,EAAE,WAAW,EAAE,SAAS,CAAC,CAAC;YAEhF,OAAO;YACP,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC;gBACrB,QAAQ,EAAE,WAAW;gBACrB,KAAK,EAAE,YAAY;gBACnB,YAAY,EAAE,YAAY;gBAC1B,gBAAgB,EAAE,WAAW;aAC9B,CAAC,CAAC;QACL,CAAC,CAAA,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"common.d.ts","sourceRoot":"","sources":["../src/common.ts"],"names":[],"mappings":"AAEA,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAI7D"}
|
package/lib-es/common.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"common.js","sourceRoot":"","sources":["../src/common.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAE5C,MAAM,UAAU,gBAAgB,CAAC,GAAoB;IACnD,OAAO,GAAG,KAAK,MAAM;QACnB,CAAC,CAAC,MAAM,CAAC,0BAA0B,CAAC;QACpC,CAAC,CAAC,qCAAqC,CAAC;AAC5C,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;;;;AAE3C,wBAEE"}
|
package/lib-es/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAE3C,eAAe;IACb,eAAe;CAChB,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export type OwnerInfo = {
|
|
2
|
+
tokenAccount: string;
|
|
3
|
+
owner: string;
|
|
4
|
+
contract: string;
|
|
5
|
+
signedDescriptor: string;
|
|
6
|
+
};
|
|
7
|
+
export declare function getOwnerAddress(tokenAddress: string, challenge: string, env?: "prod" | "test"): Promise<OwnerInfo>;
|
|
8
|
+
export declare function computedTokenAddress(address: string, mintAddress: string, challenge: string, env?: "prod" | "test"): Promise<OwnerInfo>;
|
|
9
|
+
//# sourceMappingURL=solana.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"solana.d.ts","sourceRoot":"","sources":["../src/solana.ts"],"names":[],"mappings":"AAYA,MAAM,MAAM,SAAS,GAAG;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,gBAAgB,EAAE,MAAM,CAAC;CAC1B,CAAC;AAEF,wBAAsB,eAAe,CACnC,YAAY,EAAE,MAAM,EACpB,SAAS,EAAE,MAAM,EACjB,GAAG,GAAE,MAAM,GAAG,MAAe,GAC5B,OAAO,CAAC,SAAS,CAAC,CAYpB;AAED,wBAAsB,oBAAoB,CACxC,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EACjB,GAAG,GAAE,MAAM,GAAG,MAAe,GAC5B,OAAO,CAAC,SAAS,CAAC,CAYpB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"solana.integ.test.d.ts","sourceRoot":"","sources":["../src/solana.integ.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import { computedTokenAddress, getOwnerAddress } from "./solana";
|
|
11
|
+
describe("getOwnerAddress", () => {
|
|
12
|
+
it("returns expected ATA info", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
13
|
+
// When
|
|
14
|
+
const result = yield getOwnerAddress("EQ96zptNAWwM23m5v2ByChCMTFu6zUmJgRtUrQV1uYNM", "", "test");
|
|
15
|
+
// Then
|
|
16
|
+
expect(result).toEqual(expect.objectContaining({
|
|
17
|
+
tokenAccount: "EQ96zptNAWwM23m5v2ByChCMTFu6zUmJgRtUrQV1uYNM",
|
|
18
|
+
owner: "AS1kiySqqS6Tvv3KmBsr8Zbg4DUo5fDxDD9v1dF1TVYr",
|
|
19
|
+
contract: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
|
|
20
|
+
}));
|
|
21
|
+
}));
|
|
22
|
+
});
|
|
23
|
+
describe("computedTokenAddress", () => {
|
|
24
|
+
it("returns expected ATA info", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
25
|
+
// When
|
|
26
|
+
const result = yield computedTokenAddress("DHTPaexpcpK58w4UpvoLnFH55jfwJdpg4R73mUwryZU8", "4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU", "", "test");
|
|
27
|
+
// Then
|
|
28
|
+
expect(result).toEqual(expect.objectContaining({
|
|
29
|
+
tokenAccount: "GizbHjLkKspW5XzkUsWKSoWW3VwBJMYi39NwCmppsbRs",
|
|
30
|
+
owner: "DHTPaexpcpK58w4UpvoLnFH55jfwJdpg4R73mUwryZU8",
|
|
31
|
+
contract: "4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU",
|
|
32
|
+
}));
|
|
33
|
+
}));
|
|
34
|
+
});
|
|
35
|
+
//# sourceMappingURL=solana.integ.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"solana.integ.test.js","sourceRoot":"","sources":["../src/solana.integ.test.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAEjE,QAAQ,CAAC,iBAAiB,EAAE,GAAG,EAAE;IAC/B,EAAE,CAAC,2BAA2B,EAAE,GAAS,EAAE;QACzC,OAAO;QACP,MAAM,MAAM,GAAG,MAAM,eAAe,CAClC,8CAA8C,EAC9C,EAAE,EACF,MAAM,CACP,CAAC;QAEF,OAAO;QACP,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CACpB,MAAM,CAAC,gBAAgB,CAAC;YACtB,YAAY,EAAE,8CAA8C;YAC5D,KAAK,EAAE,8CAA8C;YACrD,QAAQ,EAAE,8CAA8C;SACzD,CAAC,CACH,CAAC;IACJ,CAAC,CAAA,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,sBAAsB,EAAE,GAAG,EAAE;IACpC,EAAE,CAAC,2BAA2B,EAAE,GAAS,EAAE;QACzC,OAAO;QACP,MAAM,MAAM,GAAG,MAAM,oBAAoB,CACvC,8CAA8C,EAC9C,8CAA8C,EAC9C,EAAE,EACF,MAAM,CACP,CAAC;QAEF,OAAO;QACP,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CACpB,MAAM,CAAC,gBAAgB,CAAC;YACtB,YAAY,EAAE,8CAA8C;YAC5D,KAAK,EAAE,8CAA8C;YACrD,QAAQ,EAAE,8CAA8C;SACzD,CAAC,CACH,CAAC;IACJ,CAAC,CAAA,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
package/lib-es/solana.js
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import network from "@ledgerhq/live-network";
|
|
11
|
+
import { getTrustedDomain } from "./common";
|
|
12
|
+
export function getOwnerAddress(tokenAddress_1, challenge_1) {
|
|
13
|
+
return __awaiter(this, arguments, void 0, function* (tokenAddress, challenge, env = "prod") {
|
|
14
|
+
const { data } = yield network({
|
|
15
|
+
method: "GET",
|
|
16
|
+
url: `${getTrustedDomain(env)}/v2/solana/owner/${tokenAddress}?challenge=${challenge}`,
|
|
17
|
+
});
|
|
18
|
+
return {
|
|
19
|
+
tokenAccount: data.tokenAccount,
|
|
20
|
+
owner: data.owner,
|
|
21
|
+
contract: data.contract,
|
|
22
|
+
signedDescriptor: data.signedDescriptor,
|
|
23
|
+
};
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
export function computedTokenAddress(address_1, mintAddress_1, challenge_1) {
|
|
27
|
+
return __awaiter(this, arguments, void 0, function* (address, mintAddress, challenge, env = "prod") {
|
|
28
|
+
const { data } = yield network({
|
|
29
|
+
method: "GET",
|
|
30
|
+
url: `${getTrustedDomain(env)}/v2/solana/computed-token-account/${address}/${mintAddress}?challenge=${challenge}`,
|
|
31
|
+
});
|
|
32
|
+
return {
|
|
33
|
+
tokenAccount: data.tokenAccount,
|
|
34
|
+
owner: data.owner,
|
|
35
|
+
contract: data.contract,
|
|
36
|
+
signedDescriptor: data.signedDescriptor,
|
|
37
|
+
};
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=solana.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"solana.js","sourceRoot":"","sources":["../src/solana.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,OAAO,MAAM,wBAAwB,CAAC;AAC7C,OAAO,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAkB5C,MAAM,UAAgB,eAAe;yDACnC,YAAoB,EACpB,SAAiB,EACjB,MAAuB,MAAM;QAE7B,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,OAAO,CAAuB;YACnD,MAAM,EAAE,KAAK;YACb,GAAG,EAAE,GAAG,gBAAgB,CAAC,GAAG,CAAC,oBAAoB,YAAY,cAAc,SAAS,EAAE;SACvF,CAAC,CAAC;QAEH,OAAO;YACL,YAAY,EAAE,IAAI,CAAC,YAAY;YAC/B,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,gBAAgB,EAAE,IAAI,CAAC,gBAAgB;SACxC,CAAC;IACJ,CAAC;CAAA;AAED,MAAM,UAAgB,oBAAoB;yDACxC,OAAe,EACf,WAAmB,EACnB,SAAiB,EACjB,MAAuB,MAAM;QAE7B,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,OAAO,CAAuB;YACnD,MAAM,EAAE,KAAK;YACb,GAAG,EAAE,GAAG,gBAAgB,CAAC,GAAG,CAAC,qCAAqC,OAAO,IAAI,WAAW,cAAc,SAAS,EAAE;SAClH,CAAC,CAAC;QAEH,OAAO;YACL,YAAY,EAAE,IAAI,CAAC,YAAY;YAC/B,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,gBAAgB,EAAE,IAAI,CAAC,gBAAgB;SACxC,CAAC;IACJ,CAAC;CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"solana.test.d.ts","sourceRoot":"","sources":["../src/solana.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import { computedTokenAddress, getOwnerAddress } from "./solana";
|
|
11
|
+
import network from "@ledgerhq/live-network";
|
|
12
|
+
jest.mock("@ledgerhq/live-network");
|
|
13
|
+
describe("solana", () => {
|
|
14
|
+
beforeEach(() => {
|
|
15
|
+
jest.resetModules();
|
|
16
|
+
jest.clearAllMocks();
|
|
17
|
+
});
|
|
18
|
+
describe("getOwnerAddress", () => {
|
|
19
|
+
it.each([
|
|
20
|
+
["prod", "https://nft.api.live.ledger.com"],
|
|
21
|
+
[undefined, "https://nft.api.live.ledger.com"],
|
|
22
|
+
["test", "https://nft.api.live.ledger-stg.com"],
|
|
23
|
+
])("fetch the correct %s service environement", (env, baseUrl) => __awaiter(void 0, void 0, void 0, function* () {
|
|
24
|
+
// Given
|
|
25
|
+
const ownerAddress = "SOL_ADDR";
|
|
26
|
+
const challenge = "WHATEVER_CHALLENGE";
|
|
27
|
+
const mockResponse = {};
|
|
28
|
+
network.mockResolvedValue({ data: mockResponse });
|
|
29
|
+
// When
|
|
30
|
+
yield getOwnerAddress(ownerAddress, challenge, env);
|
|
31
|
+
// Then
|
|
32
|
+
expect(network).toHaveBeenCalledWith({
|
|
33
|
+
method: "GET",
|
|
34
|
+
url: `${baseUrl}/v2/solana/owner/${ownerAddress}?challenge=${challenge}`,
|
|
35
|
+
});
|
|
36
|
+
}));
|
|
37
|
+
it("transforms data as expected", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
38
|
+
// Given
|
|
39
|
+
const ownerAddress = "SOL_ADDR";
|
|
40
|
+
const challenge = "WHATEVER_CHALLENGE";
|
|
41
|
+
const mintAddress = "MINT_ADDR";
|
|
42
|
+
const tokenAddress = "TOKEN_ADDR";
|
|
43
|
+
const mockResponse = {
|
|
44
|
+
descriptorType: "TrustedName",
|
|
45
|
+
descriptorVersion: 2,
|
|
46
|
+
tokenAccount: tokenAddress,
|
|
47
|
+
owner: ownerAddress,
|
|
48
|
+
contract: mintAddress,
|
|
49
|
+
signedDescriptor: "SIGNATURE",
|
|
50
|
+
};
|
|
51
|
+
network.mockResolvedValue({ data: mockResponse });
|
|
52
|
+
// When
|
|
53
|
+
const result = yield getOwnerAddress(ownerAddress, challenge);
|
|
54
|
+
// Then
|
|
55
|
+
expect(result).toEqual({
|
|
56
|
+
contract: mintAddress,
|
|
57
|
+
owner: ownerAddress,
|
|
58
|
+
tokenAccount: tokenAddress,
|
|
59
|
+
signedDescriptor: "SIGNATURE",
|
|
60
|
+
});
|
|
61
|
+
}));
|
|
62
|
+
});
|
|
63
|
+
describe("computedTokenAddress", () => {
|
|
64
|
+
it.each([
|
|
65
|
+
["prod", "https://nft.api.live.ledger.com"],
|
|
66
|
+
[undefined, "https://nft.api.live.ledger.com"],
|
|
67
|
+
["test", "https://nft.api.live.ledger-stg.com"],
|
|
68
|
+
])("fetch the correct %s service environement", (env, baseUrl) => __awaiter(void 0, void 0, void 0, function* () {
|
|
69
|
+
// Given
|
|
70
|
+
const ownerAddress = "SOL_ADDR";
|
|
71
|
+
const mintAddress = "MINT_ADDR";
|
|
72
|
+
const challenge = "WHATEVER_CHALLENGE";
|
|
73
|
+
const mockResponse = {};
|
|
74
|
+
network.mockResolvedValue({ data: mockResponse });
|
|
75
|
+
// When
|
|
76
|
+
yield computedTokenAddress(ownerAddress, mintAddress, challenge, env);
|
|
77
|
+
// Then
|
|
78
|
+
expect(network).toHaveBeenCalledWith({
|
|
79
|
+
method: "GET",
|
|
80
|
+
url: `${baseUrl}/v2/solana/computed-token-account/${ownerAddress}/${mintAddress}?challenge=${challenge}`,
|
|
81
|
+
});
|
|
82
|
+
}));
|
|
83
|
+
it("transforms data as expected", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
84
|
+
// Given
|
|
85
|
+
const ownerAddress = "SOL_ADDR";
|
|
86
|
+
const challenge = "WHATEVER_CHALLENGE";
|
|
87
|
+
const mintAddress = "MINT_ADDR";
|
|
88
|
+
const tokenAddress = "TOKEN_ADDR";
|
|
89
|
+
const mockResponse = {
|
|
90
|
+
descriptorType: "TrustedName",
|
|
91
|
+
descriptorVersion: 2,
|
|
92
|
+
tokenAccount: tokenAddress,
|
|
93
|
+
owner: ownerAddress,
|
|
94
|
+
contract: mintAddress,
|
|
95
|
+
signedDescriptor: "SIGNATURE",
|
|
96
|
+
};
|
|
97
|
+
network.mockResolvedValue({ data: mockResponse });
|
|
98
|
+
// When
|
|
99
|
+
const result = yield computedTokenAddress(ownerAddress, mintAddress, challenge);
|
|
100
|
+
// Then
|
|
101
|
+
expect(result).toEqual({
|
|
102
|
+
contract: mintAddress,
|
|
103
|
+
owner: ownerAddress,
|
|
104
|
+
tokenAccount: tokenAddress,
|
|
105
|
+
signedDescriptor: "SIGNATURE",
|
|
106
|
+
});
|
|
107
|
+
}));
|
|
108
|
+
});
|
|
109
|
+
});
|
|
110
|
+
//# sourceMappingURL=solana.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"solana.test.js","sourceRoot":"","sources":["../src/solana.test.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@ledgerhq/ledger-trust-service",
|
|
3
|
+
"version": "0.1.0-next.0",
|
|
4
|
+
"description": "Ledger Trust service client",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"Ledger",
|
|
7
|
+
"Services",
|
|
8
|
+
"Trust"
|
|
9
|
+
],
|
|
10
|
+
"repository": {
|
|
11
|
+
"type": "git",
|
|
12
|
+
"url": "https://github.com/LedgerHQ/ledger-live.git"
|
|
13
|
+
},
|
|
14
|
+
"bugs": {
|
|
15
|
+
"url": "https://github.com/LedgerHQ/ledger-live/issues"
|
|
16
|
+
},
|
|
17
|
+
"homepage": "https://github.com/LedgerHQ/ledger-live/tree/develop/libs/ledger-service/trust",
|
|
18
|
+
"main": "lib/index.js",
|
|
19
|
+
"module": "lib-es/index.js",
|
|
20
|
+
"types": "lib/index.d.ts",
|
|
21
|
+
"typesVersions": {
|
|
22
|
+
"*": {
|
|
23
|
+
"*.json": [
|
|
24
|
+
"*.json"
|
|
25
|
+
],
|
|
26
|
+
"*": [
|
|
27
|
+
"lib/*"
|
|
28
|
+
],
|
|
29
|
+
"lib/*": [
|
|
30
|
+
"lib/*"
|
|
31
|
+
],
|
|
32
|
+
"lib-es/*": [
|
|
33
|
+
"lib-es/*"
|
|
34
|
+
]
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
"exports": {
|
|
38
|
+
"./lib/*": "./lib/*.js",
|
|
39
|
+
"./lib/*.js": "./lib/*.js",
|
|
40
|
+
"./lib-es/*": "./lib-es/*.js",
|
|
41
|
+
"./lib-es/*.js": "./lib-es/*.js",
|
|
42
|
+
"./*": {
|
|
43
|
+
"require": "./lib/*.js",
|
|
44
|
+
"default": "./lib-es/*.js"
|
|
45
|
+
},
|
|
46
|
+
"./*.js": {
|
|
47
|
+
"require": "./lib/*.js",
|
|
48
|
+
"default": "./lib-es/*.js"
|
|
49
|
+
},
|
|
50
|
+
".": {
|
|
51
|
+
"require": "./lib/index.js",
|
|
52
|
+
"default": "./lib-es/index.js"
|
|
53
|
+
},
|
|
54
|
+
"./package.json": "./package.json"
|
|
55
|
+
},
|
|
56
|
+
"license": "Apache-2.0",
|
|
57
|
+
"dependencies": {
|
|
58
|
+
"@ledgerhq/live-env": "2.4.1",
|
|
59
|
+
"@ledgerhq/live-network": "2.0.3"
|
|
60
|
+
},
|
|
61
|
+
"devDependencies": {
|
|
62
|
+
"@types/jest": "^29.5.10",
|
|
63
|
+
"@types/node": "^20.11.0",
|
|
64
|
+
"dotenv": "^16.4.5",
|
|
65
|
+
"expect": "^27.5.1",
|
|
66
|
+
"jest": "^29.7.0",
|
|
67
|
+
"msw": "^2.2.13",
|
|
68
|
+
"ts-jest": "^29.1.1",
|
|
69
|
+
"ts-node": "^10.9.2"
|
|
70
|
+
},
|
|
71
|
+
"scripts": {
|
|
72
|
+
"clean": "rimraf lib lib-es",
|
|
73
|
+
"build": "tsc && tsc -m ES6 --outDir lib-es",
|
|
74
|
+
"coverage": "jest --coverage --passWithNoTests",
|
|
75
|
+
"prewatch": "pnpm build",
|
|
76
|
+
"watch": "tsc --watch",
|
|
77
|
+
"watch:es": "tsc --watch -m ES6 --outDir lib-es",
|
|
78
|
+
"lint": "eslint ./src --no-error-on-unmatched-pattern --ext .ts --cache",
|
|
79
|
+
"lint:fix": "pnpm lint --fix",
|
|
80
|
+
"typecheck": "tsc --noEmit",
|
|
81
|
+
"test": "jest",
|
|
82
|
+
"test-integ": "DOTENV_CONFIG_PATH=.env.integ.test jest --config=jest.integ.config.js",
|
|
83
|
+
"unimported": "unimported"
|
|
84
|
+
}
|
|
85
|
+
}
|
package/src/common.ts
ADDED
package/src/index.ts
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { computedTokenAddress, getOwnerAddress } from "./solana";
|
|
2
|
+
|
|
3
|
+
describe("getOwnerAddress", () => {
|
|
4
|
+
it("returns expected ATA info", async () => {
|
|
5
|
+
// When
|
|
6
|
+
const result = await getOwnerAddress(
|
|
7
|
+
"EQ96zptNAWwM23m5v2ByChCMTFu6zUmJgRtUrQV1uYNM",
|
|
8
|
+
"",
|
|
9
|
+
"test",
|
|
10
|
+
);
|
|
11
|
+
|
|
12
|
+
// Then
|
|
13
|
+
expect(result).toEqual(
|
|
14
|
+
expect.objectContaining({
|
|
15
|
+
tokenAccount: "EQ96zptNAWwM23m5v2ByChCMTFu6zUmJgRtUrQV1uYNM",
|
|
16
|
+
owner: "AS1kiySqqS6Tvv3KmBsr8Zbg4DUo5fDxDD9v1dF1TVYr",
|
|
17
|
+
contract: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
|
|
18
|
+
}),
|
|
19
|
+
);
|
|
20
|
+
});
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
describe("computedTokenAddress", () => {
|
|
24
|
+
it("returns expected ATA info", async () => {
|
|
25
|
+
// When
|
|
26
|
+
const result = await computedTokenAddress(
|
|
27
|
+
"DHTPaexpcpK58w4UpvoLnFH55jfwJdpg4R73mUwryZU8",
|
|
28
|
+
"4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU",
|
|
29
|
+
"",
|
|
30
|
+
"test",
|
|
31
|
+
);
|
|
32
|
+
|
|
33
|
+
// Then
|
|
34
|
+
expect(result).toEqual(
|
|
35
|
+
expect.objectContaining({
|
|
36
|
+
tokenAccount: "GizbHjLkKspW5XzkUsWKSoWW3VwBJMYi39NwCmppsbRs",
|
|
37
|
+
owner: "DHTPaexpcpK58w4UpvoLnFH55jfwJdpg4R73mUwryZU8",
|
|
38
|
+
contract: "4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU",
|
|
39
|
+
}),
|
|
40
|
+
);
|
|
41
|
+
});
|
|
42
|
+
});
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { computedTokenAddress, getOwnerAddress } from "./solana";
|
|
2
|
+
import network from "@ledgerhq/live-network";
|
|
3
|
+
|
|
4
|
+
jest.mock("@ledgerhq/live-network");
|
|
5
|
+
|
|
6
|
+
describe("solana", () => {
|
|
7
|
+
beforeEach(() => {
|
|
8
|
+
jest.resetModules();
|
|
9
|
+
jest.clearAllMocks();
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
describe("getOwnerAddress", () => {
|
|
13
|
+
it.each([
|
|
14
|
+
["prod", "https://nft.api.live.ledger.com"],
|
|
15
|
+
[undefined, "https://nft.api.live.ledger.com"],
|
|
16
|
+
["test", "https://nft.api.live.ledger-stg.com"],
|
|
17
|
+
])("fetch the correct %s service environement", async (env, baseUrl) => {
|
|
18
|
+
// Given
|
|
19
|
+
const ownerAddress = "SOL_ADDR";
|
|
20
|
+
const challenge = "WHATEVER_CHALLENGE";
|
|
21
|
+
const mockResponse = {};
|
|
22
|
+
(network as jest.Mock).mockResolvedValue({ data: mockResponse });
|
|
23
|
+
|
|
24
|
+
// When
|
|
25
|
+
await getOwnerAddress(ownerAddress, challenge, env as "prod" | "test");
|
|
26
|
+
|
|
27
|
+
// Then
|
|
28
|
+
expect(network).toHaveBeenCalledWith({
|
|
29
|
+
method: "GET",
|
|
30
|
+
url: `${baseUrl}/v2/solana/owner/${ownerAddress}?challenge=${challenge}`,
|
|
31
|
+
});
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
it("transforms data as expected", async () => {
|
|
35
|
+
// Given
|
|
36
|
+
const ownerAddress = "SOL_ADDR";
|
|
37
|
+
const challenge = "WHATEVER_CHALLENGE";
|
|
38
|
+
const mintAddress = "MINT_ADDR";
|
|
39
|
+
const tokenAddress = "TOKEN_ADDR";
|
|
40
|
+
const mockResponse = {
|
|
41
|
+
descriptorType: "TrustedName",
|
|
42
|
+
descriptorVersion: 2,
|
|
43
|
+
tokenAccount: tokenAddress,
|
|
44
|
+
owner: ownerAddress,
|
|
45
|
+
contract: mintAddress,
|
|
46
|
+
signedDescriptor: "SIGNATURE",
|
|
47
|
+
};
|
|
48
|
+
(network as jest.Mock).mockResolvedValue({ data: mockResponse });
|
|
49
|
+
|
|
50
|
+
// When
|
|
51
|
+
const result = await getOwnerAddress(ownerAddress, challenge);
|
|
52
|
+
|
|
53
|
+
// Then
|
|
54
|
+
expect(result).toEqual({
|
|
55
|
+
contract: mintAddress,
|
|
56
|
+
owner: ownerAddress,
|
|
57
|
+
tokenAccount: tokenAddress,
|
|
58
|
+
signedDescriptor: "SIGNATURE",
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
describe("computedTokenAddress", () => {
|
|
64
|
+
it.each([
|
|
65
|
+
["prod", "https://nft.api.live.ledger.com"],
|
|
66
|
+
[undefined, "https://nft.api.live.ledger.com"],
|
|
67
|
+
["test", "https://nft.api.live.ledger-stg.com"],
|
|
68
|
+
])("fetch the correct %s service environement", async (env, baseUrl) => {
|
|
69
|
+
// Given
|
|
70
|
+
const ownerAddress = "SOL_ADDR";
|
|
71
|
+
const mintAddress = "MINT_ADDR";
|
|
72
|
+
const challenge = "WHATEVER_CHALLENGE";
|
|
73
|
+
const mockResponse = {};
|
|
74
|
+
(network as jest.Mock).mockResolvedValue({ data: mockResponse });
|
|
75
|
+
|
|
76
|
+
// When
|
|
77
|
+
await computedTokenAddress(ownerAddress, mintAddress, challenge, env as "prod" | "test");
|
|
78
|
+
|
|
79
|
+
// Then
|
|
80
|
+
expect(network).toHaveBeenCalledWith({
|
|
81
|
+
method: "GET",
|
|
82
|
+
url: `${baseUrl}/v2/solana/computed-token-account/${ownerAddress}/${mintAddress}?challenge=${challenge}`,
|
|
83
|
+
});
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
it("transforms data as expected", async () => {
|
|
87
|
+
// Given
|
|
88
|
+
const ownerAddress = "SOL_ADDR";
|
|
89
|
+
const challenge = "WHATEVER_CHALLENGE";
|
|
90
|
+
const mintAddress = "MINT_ADDR";
|
|
91
|
+
const tokenAddress = "TOKEN_ADDR";
|
|
92
|
+
const mockResponse = {
|
|
93
|
+
descriptorType: "TrustedName",
|
|
94
|
+
descriptorVersion: 2,
|
|
95
|
+
tokenAccount: tokenAddress,
|
|
96
|
+
owner: ownerAddress,
|
|
97
|
+
contract: mintAddress,
|
|
98
|
+
signedDescriptor: "SIGNATURE",
|
|
99
|
+
};
|
|
100
|
+
(network as jest.Mock).mockResolvedValue({ data: mockResponse });
|
|
101
|
+
|
|
102
|
+
// When
|
|
103
|
+
const result = await computedTokenAddress(ownerAddress, mintAddress, challenge);
|
|
104
|
+
|
|
105
|
+
// Then
|
|
106
|
+
expect(result).toEqual({
|
|
107
|
+
contract: mintAddress,
|
|
108
|
+
owner: ownerAddress,
|
|
109
|
+
tokenAccount: tokenAddress,
|
|
110
|
+
signedDescriptor: "SIGNATURE",
|
|
111
|
+
});
|
|
112
|
+
});
|
|
113
|
+
});
|
|
114
|
+
});
|
package/src/solana.ts
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import network from "@ledgerhq/live-network";
|
|
2
|
+
import { getTrustedDomain } from "./common";
|
|
3
|
+
|
|
4
|
+
type OwnerAddressResponse = {
|
|
5
|
+
descriptorType: "TrustedName";
|
|
6
|
+
descriptorVersion: number;
|
|
7
|
+
tokenAccount: string;
|
|
8
|
+
owner: string;
|
|
9
|
+
contract: string;
|
|
10
|
+
signedDescriptor: string;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export type OwnerInfo = {
|
|
14
|
+
tokenAccount: string;
|
|
15
|
+
owner: string;
|
|
16
|
+
contract: string;
|
|
17
|
+
signedDescriptor: string;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export async function getOwnerAddress(
|
|
21
|
+
tokenAddress: string,
|
|
22
|
+
challenge: string,
|
|
23
|
+
env: "prod" | "test" = "prod",
|
|
24
|
+
): Promise<OwnerInfo> {
|
|
25
|
+
const { data } = await network<OwnerAddressResponse>({
|
|
26
|
+
method: "GET",
|
|
27
|
+
url: `${getTrustedDomain(env)}/v2/solana/owner/${tokenAddress}?challenge=${challenge}`,
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
return {
|
|
31
|
+
tokenAccount: data.tokenAccount,
|
|
32
|
+
owner: data.owner,
|
|
33
|
+
contract: data.contract,
|
|
34
|
+
signedDescriptor: data.signedDescriptor,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export async function computedTokenAddress(
|
|
39
|
+
address: string,
|
|
40
|
+
mintAddress: string,
|
|
41
|
+
challenge: string,
|
|
42
|
+
env: "prod" | "test" = "prod",
|
|
43
|
+
): Promise<OwnerInfo> {
|
|
44
|
+
const { data } = await network<OwnerAddressResponse>({
|
|
45
|
+
method: "GET",
|
|
46
|
+
url: `${getTrustedDomain(env)}/v2/solana/computed-token-account/${address}/${mintAddress}?challenge=${challenge}`,
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
return {
|
|
50
|
+
tokenAccount: data.tokenAccount,
|
|
51
|
+
owner: data.owner,
|
|
52
|
+
contract: data.contract,
|
|
53
|
+
signedDescriptor: data.signedDescriptor,
|
|
54
|
+
};
|
|
55
|
+
}
|
package/tsconfig.json
ADDED