From f521fb3ae8bdda62ed0418f426fd0a152b0c1e46 Mon Sep 17 00:00:00 2001 From: einaralex Date: Thu, 29 Dec 2022 16:26:36 +0000 Subject: [PATCH] test: add tests for getting and placing orders feat: add link account function --- src/client.ts | 15 ++-- src/types.ts | 37 ++++++-- test/client_test.ts | 203 ++++++++++++++++++++++++++++++++++++++++---- 3 files changed, 224 insertions(+), 31 deletions(-) diff --git a/src/client.ts b/src/client.ts index 9689719..3a92a45 100644 --- a/src/client.ts +++ b/src/client.ts @@ -9,9 +9,10 @@ import type { BearerProfile, ClientCredentials, Environment, + LinkAddress, NewOrder, Order, - OrderFiler, + OrderFilter, PKCERequest, PKCERequestArgs, Profile, @@ -140,21 +141,25 @@ export class MoneriumClient { method: string, resource: string, body?: BodyInit, - isFormEncoded?: boolean, + isFormEncoded?: boolean ) { const res = await fetch(`${this.#env.api}/${resource}`, { method, headers: { - "Content-Type": `application/${isFormEncoded ? "x-www-form-urlencoded" : "json"}`, + "Content-Type": `application/${ + isFormEncoded ? "x-www-form-urlencoded" : "json" + }`, Authorization: this.#authPayload || "", }, body, }); + let response = await res.json(); + if (res.ok) { - return await res.json(); + return response; } else { - throw new Error(`${resource}: ${res.statusText}`); + throw response; } } diff --git a/src/types.ts b/src/types.ts index 79a8a6a..d644d1b 100644 --- a/src/types.ts +++ b/src/types.ts @@ -19,7 +19,7 @@ export interface BearerProfile { // --- Client Methods --- // -enum Currency { +export enum Currency { eur = "eur", usd = "usd", gbp = "gbp", @@ -130,7 +130,7 @@ type KYC = { outcome: KYCOutcome; }; -enum PaymentStandard { +export enum PaymentStandard { iban = "iban", scan = "scan", } @@ -142,6 +142,9 @@ type Account = { iban?: string; sortCode?: string; accountNumber?: string; + network: Network; + chain: Chain; + id?: string; }; export interface Profile { @@ -153,16 +156,15 @@ export interface Profile { // -- getBalances -enum Chain { +export enum Chain { polygon = "polygon", ethereum = "ethereum", + gnosis = "gnosis", } -enum Network { +export enum Network { mainnet = "mainnet", - ropsten = "ropsten", - rinkeby = "rinkeby", - kovan = "kovan", + chiado = "chiado", goerli = "goerli", mumbai = "mumbai", } @@ -182,7 +184,7 @@ export interface Balances { // --getOrders -enum OrderKind { +export enum OrderKind { redeem = "redeem", issue = "issue", } @@ -214,10 +216,12 @@ type SCAN = { type Individual = { firstName: string; lastName: string; + country?: string; }; type Corporation = { companyName: string; + country: string; }; type Counterpart = { @@ -236,7 +240,7 @@ type OrderMetadata = { sentAmount: string; }; -export interface OrderFiler { +export interface OrderFilter { address?: string; txHash?: string; profile?: string; @@ -307,3 +311,18 @@ export interface SupportingDoc { hash: string; meta: SupportingDocMetadata; } + +// -- linkAddress + +interface CurrencyAccounts { + network: Network; + chain: Chain; + currency: Currency; +} + +export interface LinkAddress { + address: string; + message: string; + signature: string; + accounts: CurrencyAccounts[]; +} diff --git a/test/client_test.ts b/test/client_test.ts index b85dc8b..839d94e 100644 --- a/test/client_test.ts +++ b/test/client_test.ts @@ -2,11 +2,33 @@ import { assertArrayIncludes, assertInstanceOf, assertObjectMatch, -} from "https://deno.land/std@0.159.0/testing/asserts.ts"; + assertEquals, +} from "https://deno.land/std@0.168.0/testing/asserts.ts"; + import { MoneriumClient } from "../mod.ts"; +import { + Chain, + Currency, + Network, + OrderKind, + PaymentStandard, + Order, +} from "../src/types.ts"; const clientId = "654c9c30-44d3-11ed-adac-b2efc0e6677d"; -const clientSecret = "ac474b7cdc111973aa080b0428ba3a824e82119bee8f65875b4aba0d42416dff"; +const clientSecret = + "ac474b7cdc111973aa080b0428ba3a824e82119bee8f65875b4aba0d42416dff"; + +// punkWallet: https://punkwallet.io/pk#0x3e4936f901535680c505b073a5f70094da38e2085ecf137b153d1866a7aa826b +const publicKey = "0x2d312198e570912844b5a230AE6f7A2E3321371C"; +const privateKey = + "0x3e4936f901535680c505b073a5f70094da38e2085ecf137b153d1866a7aa826b"; + +const message = "I hereby declare that I am the address owner."; + +// TODO: use ethers to generate signatures. +const ownerSignatureHash = + "0xe206a1b5a268c9161d6874eeeab49cff554fddf485389b744491cf3920e6881d697c48a2e76453d04179b55d757365e2c591e9e8ad40f129c8f4bb592692f4031c"; Deno.test("client initialization", () => { const client = new MoneriumClient(); @@ -24,7 +46,47 @@ Deno.test("authenticate with client credentials", async () => { const authContext = await client.getAuthContext(); - assertObjectMatch(authContext, { userId: "05cc17db-17d0-11ed-81e7-a6f0ef57aabb" }); + assertObjectMatch(authContext, { + userId: "05cc17db-17d0-11ed-81e7-a6f0ef57aabb", + }); +}); + +Deno.test("link address", async () => { + const client = new MoneriumClient(); + + await client.auth({ + client_id: clientId, + client_secret: clientSecret, + }); + + const authContext = await client.getAuthContext(); + + try { + await client.linkAddress(authContext.defaultProfile, { + address: publicKey, + message: message, + signature: ownerSignatureHash, + accounts: [ + { + network: Network.goerli, + chain: Chain.ethereum, + currency: Currency.eur, + }, + { + network: Network.chiado, + chain: Chain.gnosis, + currency: Currency.eur, + }, + { + network: Network.mumbai, + chain: Chain.polygon, + currency: Currency.eur, + }, + ], + }); + } catch (e) { + assertEquals("Account already linked to your profile", e.errors?.address); + } }); Deno.test("get profile", async () => { @@ -38,7 +100,9 @@ Deno.test("get profile", async () => { const authContext = await client.getAuthContext(); const profile = await client.getProfile(authContext.profiles[0].id); - assertObjectMatch(profile, { accounts: [{ id: "4b2be022-44e3-11ed-adac-b2efc0e6677d" }] }); + assertObjectMatch(profile, { + accounts: [{ id: "4b2be022-44e3-11ed-adac-b2efc0e6677d" }], + }); }); /* @@ -64,7 +128,35 @@ Deno.test("get orders", async () => { }); const orders = await client.getOrders(); + const order = orders.find( + (o: Order) => o.memo === "Powered by Monerium SDK" + ) as Order; + assertArrayIncludes(orders, []); + assertObjectMatch(order, { + kind: "redeem", + amount: "1", + memo: "Powered by Monerium SDK", + }); +}); + +Deno.test("get orders by profileId", async () => { + const profileId = "04f5b0d5-17d0-11ed-81e7-a6f0ef57aabb"; + + const client = new MoneriumClient(); + + await client.auth({ + client_id: clientId, + client_secret: clientSecret, + }); + + const orders = await client.getOrders({ + profile: profileId, + }); + + orders.map((o: Order) => { + assertEquals(profileId, o.profile); + }); }); Deno.test("get order", async () => { @@ -75,8 +167,13 @@ Deno.test("get order", async () => { client_secret: clientSecret, }); - // const order = await client.getOrder(); - // assertObjectMatch(order, {}); + const order = await client.getOrder("96cb9a3c-878d-11ed-ac14-4a76678fa2b6"); + + assertObjectMatch(order, { + kind: "redeem", + amount: "1", + memo: "Powered by Monerium SDK", + }); }); Deno.test("get tokens", async () => { @@ -89,15 +186,17 @@ Deno.test("get tokens", async () => { const tokens = await client.getTokens(); - assertArrayIncludes(tokens, [{ - currency: "eur", - ticker: "EUR", - symbol: "EURe", - chain: "ethereum", - network: "rinkeby", - address: "0x25c13fc529dc4afe4d488bd1f2ee5e1ec4918e0b", - decimals: 18, - }]); + assertArrayIncludes(tokens, [ + { + address: "0x83B844180f66Bbc3BE2E97C6179035AF91c4Cce8", + chain: "ethereum", + currency: "eur", + decimals: 18, + network: "goerli", + symbol: "EURe", + ticker: "EUR", + }, + ]); }); Deno.test("place order", async () => { @@ -107,9 +206,79 @@ Deno.test("place order", async () => { client_id: clientId, client_secret: clientSecret, }); + const authContext = await client.getAuthContext(); + const profile = await client.getProfile(authContext.profiles[0].id); + const account = profile.accounts.find( + (a) => + a.address === publicKey && + a.currency === Currency.eur && + a.network === Network.goerli + ); - // const order = client.placeOrder(); - // assertObjectMatch(order, {}); + const date = "Thu, 29 Dec 2022 14:58 +00:00"; + const placeOrderMessage = `Send EUR 10 to GR1601101250000000012300695 at ${date}`; + const placeOrderSignatureHash = + "0xe2baa7df880f140e37d4a0d9cb1aaa8969b40650f69dc826373efdcc0945050d45f64cf5a2c96fe6bba959abe1bee115cfa31cedc378233e051036cdebd992181c"; + + const order = await client.placeOrder({ + kind: OrderKind.redeem, + amount: "1", + signature: placeOrderSignatureHash, + accountId: account?.id, + address: publicKey, + currency: Currency.eur, + counterpart: { + identifier: { + standard: PaymentStandard.iban, + iban: "GR1601101250000000012300695", + }, + details: { + firstName: "Mockbank", + lastName: "Testerson", + }, + }, + message: placeOrderMessage, + memo: "Powered by Monerium SDK", + chain: Chain.ethereum, + network: Network.goerli, + }); + + const expected = { + // id: "96cb9a3c-878d-11ed-ac14-4a76678fa2b6", + profile: "04f5b0d5-17d0-11ed-81e7-a6f0ef57aabb", + accountId: "3cef7bfc-8779-11ed-ac14-4a76678fa2b6", + address: "0x2d312198e570912844b5a230AE6f7A2E3321371C", + kind: "redeem", + amount: "1", + currency: "eur", + totalFee: "0", + fees: [], + counterpart: { + details: { + name: "Mockbank Testerson", + country: "GR", + lastName: "Testerson", + firstName: "Mockbank", + }, + identifier: { + iban: "GR16 0110 1250 0000 0001 2300 695", + standard: "iban", + }, + }, + memo: "Powered by Monerium SDK", + supportingDocumentId: "", + chain: "ethereum", + network: "goerli", + txHashes: [], + meta: { + state: "placed", + placedBy: "05cc17db-17d0-11ed-81e7-a6f0ef57aabb", + // placedAt: "2022-12-29T15:29:31.924746Z", + receivedAmount: "0", + sentAmount: "0", + }, + }; + assertObjectMatch(order, expected); }); Deno.test("upload supporting document", async () => {