Skip to content

Commit

Permalink
feat: Onramp Widget and Improvements (#1865)
Browse files Browse the repository at this point in the history
  • Loading branch information
tomiir authored Feb 12, 2024
1 parent a03daca commit d9e4489
Show file tree
Hide file tree
Showing 36 changed files with 1,091 additions and 183 deletions.
2 changes: 1 addition & 1 deletion apps/gallery/stories/composites/wui-input-text.stories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export default {
},
argTypes: {
size: {
options: ['sm', 'md'],
options: ['sm', 'md', 'lg'],
control: { type: 'select' }
},
disabled: {
Expand Down
6 changes: 6 additions & 0 deletions apps/laboratory/src/components/Web3ModalButtons.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,12 @@ export function Web3ModalButtons() {
</Heading>
<w3m-network-button />
</Box>
<Box>
<Heading size="xs" textTransform="uppercase" pb="2">
Onramp Widget
</Heading>
<w3m-onramp-widget />
</Box>
</Stack>
</CardBody>
</Card>
Expand Down
2 changes: 1 addition & 1 deletion packages/common/src/utils/TypeUtil.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export type TransactionDirection = 'in' | 'out' | 'self'

export type TransactionImage = {
type: 'FUNGIBLE' | 'NFT' | undefined
url: string
url: string | undefined
}

export interface Transaction {
Expand Down
22 changes: 22 additions & 0 deletions packages/core/src/controllers/ApiController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,18 @@ export const ApiController = {
AssetController.setConnectorImage(imageId, URL.createObjectURL(blob))
},

async _fetchCurrencyImage(countryCode: string) {
const imageUrl = `${api.baseUrl}/public/getCurrencyImage/${countryCode}`
const blob = await api.getBlob({ path: imageUrl, headers: ApiController._getApiHeaders() })
AssetController.setCurrencyImage(countryCode, URL.createObjectURL(blob))
},

async _fetchTokenImage(symbol: string) {
const imageUrl = `${api.baseUrl}/public/getTokenImage/${symbol}`
const blob = await api.getBlob({ path: imageUrl, headers: ApiController._getApiHeaders() })
AssetController.setTokenImage(symbol, URL.createObjectURL(blob))
},

async fetchNetworkImages() {
const { requestedCaipNetworks } = NetworkController.state
const ids = requestedCaipNetworks?.map(({ imageId }) => imageId).filter(Boolean)
Expand All @@ -95,6 +107,16 @@ export const ApiController = {
await Promise.allSettled((ids as string[]).map(id => ApiController._fetchConnectorImage(id)))
},

async fetchCurrencyImages(currencies: string[] = []) {
await Promise.allSettled(
currencies.map(currency => ApiController._fetchCurrencyImage(currency))
)
},

async fetchTokenImages(tokens: string[] = []) {
await Promise.allSettled(tokens.map(token => ApiController._fetchTokenImage(token)))
},

async fetchFeaturedWallets() {
const { featuredWalletIds } = OptionsController.state
if (featuredWalletIds?.length) {
Expand Down
12 changes: 11 additions & 1 deletion packages/core/src/controllers/AssetController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export interface AssetControllerState {
networkImages: Record<string, string>
connectorImages: Record<string, string>
tokenImages: Record<string, string>
currencyImages: Record<string, string>
}

type StateKey = keyof AssetControllerState
Expand All @@ -16,7 +17,8 @@ const state = proxy<AssetControllerState>({
walletImages: {},
networkImages: {},
connectorImages: {},
tokenImages: {}
tokenImages: {},
currencyImages: {}
})

// -- Controller ---------------------------------------- //
Expand All @@ -31,6 +33,10 @@ export const AssetController = {
return subKey(state, key, callback)
},

subscribe(callback: (newState: AssetControllerState) => void) {
return sub(state, () => callback(state))
},

setWalletImage(key: string, value: string) {
state.walletImages[key] = value
},
Expand All @@ -45,5 +51,9 @@ export const AssetController = {

setTokenImage(key: string, value: string) {
state.tokenImages[key] = value
},

setCurrencyImage(key: string, value: string) {
state.currencyImages[key] = value
}
}
143 changes: 130 additions & 13 deletions packages/core/src/controllers/BlockchainApiController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,88 @@ import type {
BlockchainApiTransactionsRequest,
BlockchainApiTransactionsResponse,
BlockchainApiIdentityRequest,
BlockchainApiIdentityResponse
BlockchainApiIdentityResponse,
GenerateOnRampUrlArgs,
GetQuoteArgs,
OnrampQuote,
PaymentCurrency,
PurchaseCurrency
} from '../utils/TypeUtil.js'
import { OptionsController } from './OptionsController.js'

type DestinationWallet = {
address: string
blockchains: string[]
assets: string[]
}

type GenerateOnRampT = {
destinationWallets: DestinationWallet[]
partnerUserId: string
defaultNetwork?: string
const DEFAULT_OPTIONS = {
purchaseCurrencies: [
{
id: '2b92315d-eab7-5bef-84fa-089a131333f5',
name: 'USD Coin',
symbol: 'USDC',
networks: [
{
name: 'ethereum-mainnet',
display_name: 'Ethereum',
chain_id: '1',
contract_address: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48'
},
{
name: 'polygon-mainnet',
display_name: 'Polygon',
chain_id: '137',
contract_address: '0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174'
}
]
},
{
id: '2b92315d-eab7-5bef-84fa-089a131333f5',
name: 'Ether',
symbol: 'ETH',
networks: [
{
name: 'ethereum-mainnet',
display_name: 'Ethereum',
chain_id: '1',
contract_address: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48'
},
{
name: 'polygon-mainnet',
display_name: 'Polygon',
chain_id: '137',
contract_address: '0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174'
}
]
}
],
paymentCurrencies: [
{
id: 'USD',
payment_method_limits: [
{
id: 'card',
min: '10.00',
max: '7500.00'
},
{
id: 'ach_bank_account',
min: '10.00',
max: '25000.00'
}
]
},
{
id: 'EUR',
payment_method_limits: [
{
id: 'card',
min: '10.00',
max: '7500.00'
},
{
id: 'ach_bank_account',
min: '10.00',
max: '25000.00'
}
]
}
]
}

// -- Helpers ------------------------------------------- //
Expand Down Expand Up @@ -54,17 +122,66 @@ export const BlockchainApiController = {
})
},

async generateOnRampURL({ destinationWallets, partnerUserId, defaultNetwork }: GenerateOnRampT) {
async generateOnRampURL({
destinationWallets,
partnerUserId,
defaultNetwork,
purchaseAmount,
paymentAmount
}: GenerateOnRampUrlArgs) {
const response = await api.post<{ url: string }>({
path: `/v1/generators/onrampurl?projectId=${OptionsController.state.projectId}`,
body: {
destinationWallets,
defaultNetwork,
partnerUserId,
defaultExperience: 'buy'
defaultExperience: 'buy',
presetCryptoAmount: purchaseAmount,
presetFiatAmount: paymentAmount
}
})

return response.url
},

async getOnrampOptions() {
try {
const response = await api.get<{
paymentCurrencies: PaymentCurrency[]
purchaseCurrencies: PurchaseCurrency[]
}>({
path: `/v1/onramp/options?projectId=${OptionsController.state.projectId}`
})

return response
} catch (e) {
return DEFAULT_OPTIONS
}
},

async getOnrampQuote({ purchaseCurrency, paymentCurrency, amount, network }: GetQuoteArgs) {
try {
const response = await api.post<OnrampQuote>({
path: `/v1/onramp/quote?projectId=${OptionsController.state.projectId}`,
body: {
purchaseCurrency,
paymentCurrency,
amount,
network
}
})

return response
} catch (e) {
// Mocking response as 1:1 until endpoint is ready
return {
coinbaseFee: { amount, currency: paymentCurrency.id },
networkFee: { amount, currency: paymentCurrency.id },
paymentSubtotal: { amount, currency: paymentCurrency.id },
paymentTotal: { amount, currency: paymentCurrency.id },
purchaseAmount: { amount, currency: paymentCurrency.id },
quoteId: 'mocked-quote-id'
}
}
}
}
Loading

0 comments on commit d9e4489

Please sign in to comment.