Skip to content

Commit a613e2e

Browse files
committed
update
1 parent e0eea33 commit a613e2e

File tree

8 files changed

+195
-1
lines changed

8 files changed

+195
-1
lines changed

.changeset/stupid-buses-wink.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"thirdweb": minor
3+
---
4+
5+
Add 2 new Pay functions: convertFiatToCrypto and convertCryptoToFiat

packages/thirdweb/src/exports/pay.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,3 +66,13 @@ export type {
6666
PayTokenInfo,
6767
PayOnChainTransactionDetails,
6868
} from "../pay/utils/commonTypes.js";
69+
70+
export {
71+
convertFiatToCrypto,
72+
type ConvertFiatToCryptoParams,
73+
} from "../pay/convert/fiatToCrypto.js";
74+
75+
export {
76+
convertCryptoToFiat,
77+
type ConvertCryptoToFiatParams,
78+
} from "../pay/convert/cryptoToFiat.js";
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import { describe, expect, it } from "vitest";
2+
import { TEST_CLIENT } from "~test/test-clients.js";
3+
import { base } from "../../chains/chain-definitions/base.js";
4+
import { NATIVE_TOKEN_ADDRESS } from "../../constants/addresses.js";
5+
import { convertCryptoToFiat } from "./cryptoToFiat.js";
6+
7+
describe.runIf(process.env.TW_SECRET_KEY)("Pay: fiatToCrypto", () => {
8+
it("should convert ETH price to USD on Ethereum mainnet", async () => {
9+
const result = await convertCryptoToFiat({
10+
chainId: 1,
11+
fromTokenAddress: NATIVE_TOKEN_ADDRESS,
12+
fromAmount: 2,
13+
to: "usd",
14+
client: TEST_CLIENT,
15+
});
16+
expect(result).toBeDefined();
17+
// Should be a number
18+
expect(!Number.isNaN(Number(result))).toBe(true);
19+
// Since eth is around US$3000, we can add a test to check if the price is greater than $1500 (as a safe margin)
20+
// let's hope that scenario does not happen :(
21+
expect(Number(result) > 1500).toBe(true);
22+
});
23+
24+
it("should convert ETH price to USD on Base mainnet", async () => {
25+
const result = await convertCryptoToFiat({
26+
chainId: 1,
27+
fromTokenAddress: NATIVE_TOKEN_ADDRESS,
28+
fromAmount: base.id,
29+
to: "usd",
30+
client: TEST_CLIENT,
31+
});
32+
expect(result).toBeDefined();
33+
// Should be a number
34+
expect(!Number.isNaN(Number(result))).toBe(true);
35+
// Since eth is around US$3000, we can add a test to check if the price is greater than $1500 (as a safe margin)
36+
// let's hope that scenario does not happen :(
37+
expect(Number(result) > 1500).toBe(true);
38+
});
39+
});
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import type { Address } from "abitype";
2+
import type { ThirdwebClient } from "../../client/client.js";
3+
import { getClientFetch } from "../../utils/fetch.js";
4+
import { getPayConvertCryptoToFiatEndpoint } from "../utils/definitions.js";
5+
6+
export type ConvertCryptoToFiatParams = {
7+
client: ThirdwebClient;
8+
/**
9+
* The contract address of the token
10+
* For native token, use NATIVE_TOKEN_ADDRESS
11+
*/
12+
fromTokenAddress: Address;
13+
fromAmount: number;
14+
/**
15+
* The chainId that the token is deployed to
16+
*/
17+
chainId: number;
18+
/**
19+
* The fiat symbol. e.g "usd"
20+
*/
21+
to: string;
22+
};
23+
24+
export async function convertCryptoToFiat(options: ConvertCryptoToFiatParams) {
25+
const { client, fromTokenAddress, to, chainId, fromAmount } = options;
26+
try {
27+
const queryString = new URLSearchParams({
28+
fromTokenAddress,
29+
to,
30+
chainId: String(chainId),
31+
fromAmount: String(fromAmount),
32+
}).toString();
33+
const url = `${getPayConvertCryptoToFiatEndpoint()}?${queryString}`;
34+
const response = await getClientFetch(client)(url);
35+
// Assuming the response directly matches the BuyWithCryptoStatus interface
36+
if (!response.ok) {
37+
response.body?.cancel();
38+
throw new Error(`HTTP error! status: ${response.status}`);
39+
}
40+
41+
const data: string = (await response.json()).result;
42+
return data;
43+
} catch (error) {
44+
console.error("Fetch error:", error);
45+
throw new Error(`Fetch failed: ${error}`);
46+
}
47+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import { describe, expect, it } from "vitest";
2+
import { TEST_CLIENT } from "~test/test-clients.js";
3+
import { base } from "../../chains/chain-definitions/base.js";
4+
import { NATIVE_TOKEN_ADDRESS } from "../../constants/addresses.js";
5+
import { convertFiatToCrypto } from "./fiatToCrypto.js";
6+
7+
describe.runIf(process.env.TW_SECRET_KEY)("Pay: fiatToCrypto", () => {
8+
it("should convert fiat price to token on Ethereum mainnet", async () => {
9+
const result = await convertFiatToCrypto({
10+
chainId: 1,
11+
from: "usd",
12+
fromAmount: 1,
13+
to: NATIVE_TOKEN_ADDRESS,
14+
client: TEST_CLIENT,
15+
});
16+
expect(result).toBeDefined();
17+
// Should be a number
18+
expect(!Number.isNaN(Number(result))).toBe(true);
19+
// Since eth is around US$3000, 1 USD should be around 0.0003
20+
// we give it some safe margin so the test won't be flaky
21+
expect(Number(result) < 0.001).toBe(true);
22+
});
23+
24+
it("should convert fiat price to token on Base mainnet", async () => {
25+
const result = await convertFiatToCrypto({
26+
chainId: base.id,
27+
from: "usd",
28+
fromAmount: 1,
29+
to: NATIVE_TOKEN_ADDRESS,
30+
client: TEST_CLIENT,
31+
});
32+
33+
expect(result).toBeDefined();
34+
// Should be a number
35+
expect(!Number.isNaN(Number(result))).toBe(true);
36+
// Since eth is around US$3000, 1 USD should be around 0.0003
37+
// we give it some safe margin so the test won't be flaky
38+
expect(Number(result) < 0.001).toBe(true);
39+
});
40+
});
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import type { Address } from "abitype";
2+
import type { ThirdwebClient } from "../../client/client.js";
3+
import { getClientFetch } from "../../utils/fetch.js";
4+
import { getPayConvertFiatToCryptoEndpoint } from "../utils/definitions.js";
5+
6+
export type ConvertFiatToCryptoParams = {
7+
client: ThirdwebClient;
8+
/**
9+
* The fiat symbol. e.g: "usd"
10+
*/
11+
from: string;
12+
fromAmount: number;
13+
/**
14+
* The token address
15+
* For native token, use NATIVE_TOKEN_ADDRESS
16+
*/
17+
to: Address;
18+
/**
19+
* The chainId that the token is deployed to
20+
*/
21+
chainId: number;
22+
};
23+
24+
export async function convertFiatToCrypto(options: ConvertFiatToCryptoParams) {
25+
const { client, from, to, chainId, fromAmount } = options;
26+
try {
27+
const queryString = new URLSearchParams({
28+
from,
29+
to,
30+
chainId: String(chainId),
31+
fromAmount: String(fromAmount),
32+
}).toString();
33+
const url = `${getPayConvertFiatToCryptoEndpoint()}?${queryString}`;
34+
const response = await getClientFetch(client)(url);
35+
// Assuming the response directly matches the BuyWithCryptoStatus interface
36+
if (!response.ok) {
37+
response.body?.cancel();
38+
throw new Error(`HTTP error! status: ${response.status}`);
39+
}
40+
41+
const data: string = (await response.json()).result;
42+
return data;
43+
} catch (error) {
44+
console.error("Fetch error:", error);
45+
throw new Error(`Fetch failed: ${error}`);
46+
}
47+
}

packages/thirdweb/src/pay/utils/definitions.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,3 +76,9 @@ export const getPaySupportedSources = () =>
7676
*/
7777
export const getPayBuyHistoryEndpoint = () =>
7878
`${getPayBaseUrl()}/wallet/history/v1`;
79+
80+
export const getPayConvertFiatToCryptoEndpoint = () =>
81+
`${getPayBaseUrl()}/convert/fiat-to-crypto/v1`;
82+
83+
export const getPayConvertCryptoToFiatEndpoint = () =>
84+
`${getPayBaseUrl()}/convert/crypto-to-fiat/v1`;

packages/thirdweb/src/utils/domains.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ type DomainOverrides = {
3939
export const DEFAULT_RPC_URL = "rpc.thirdweb.com";
4040
const DEFAULT_SOCIAL_URL = "social.thirdweb.com";
4141
const DEFAULT_IN_APP_WALLET_URL = "embedded-wallet.thirdweb.com";
42-
const DEFAULT_PAY_URL = "pay.thirdweb.com";
42+
const DEFAULT_PAY_URL = "localhost:3008"; // "pay.thirdweb.com";
4343
const DEFAULT_STORAGE_URL = "storage.thirdweb.com";
4444
const DEFAULT_BUNDLER_URL = "bundler.thirdweb.com";
4545
const DEFAULT_ANALYTICS_URL = "c.thirdweb.com";

0 commit comments

Comments
 (0)