Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for fund and quote_fund for wallet funding #322

Merged
merged 13 commits into from
Nov 27, 2024
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

## Unreleased

## Added

- Add `FundOperation` and `FundQuote` classes to support wallet funding

### Fixed
- Fixed a bug where the asset ID was not being set correctly for Gwei and Wei

Expand Down
1 change: 1 addition & 0 deletions src/client/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6523,6 +6523,7 @@ export interface FundApiInterface {
* @memberof FundApiInterface
*/
listFundOperations(walletId: string, addressId: string, limit?: number, page?: string, options?: RawAxiosRequestConfig): AxiosPromise<FundOperationList>;

}

/**
Expand Down
40 changes: 40 additions & 0 deletions src/coinbase/address/wallet_address.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ import { Wallet as WalletClass } from "../wallet";
import { StakingOperation } from "../staking_operation";
import { PayloadSignature } from "../payload_signature";
import { SmartContract } from "../smart_contract";
import { FundOperation } from "../fund_operation";
import { FundQuote } from "../fund_quote";

/**
* A representation of a blockchain address, which is a wallet-controlled account on a network.
Expand Down Expand Up @@ -747,6 +749,44 @@ export class WalletAddress extends Address {
};
}

/**
* Fund the address from your account on the Coinbase Platform.
*
* @param amount - The amount of the Asset to fund the wallet with
* @param assetId - The ID of the Asset to fund with. For Ether, eth, gwei, and wei are supported.
* @returns The created fund operation object
*/
public async fund(amount: Amount, assetId: string): Promise<FundOperation> {
const normalizedAmount = new Decimal(amount.toString());

return FundOperation.create(
this.getWalletId(),
this.getId(),
normalizedAmount,
assetId,
this.getNetworkId(),
);
}

/**
* Get a quote for funding the address from your Coinbase platform account.
*
* @param amount - The amount to fund
* @param assetId - The ID of the Asset to fund with. For Ether, eth, gwei, and wei are supported.
* @returns The fund quote object
*/
public async quoteFund(amount: Amount, assetId: string): Promise<FundQuote> {
const normalizedAmount = new Decimal(amount.toString());

return FundQuote.create(
this.getWalletId(),
this.getId(),
normalizedAmount,
assetId,
this.getNetworkId(),
);
}

/**
* Returns the address and network ID of the given destination.
*
Expand Down
2 changes: 2 additions & 0 deletions src/coinbase/coinbase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {
SmartContractsApiFactory,
TransactionHistoryApiFactory,
MPCWalletStakeApiFactory,
FundApiFactory,
} from "../client";
import { BASE_PATH } from "./../client/base";
import { Configuration } from "./../client/configuration";
Expand Down Expand Up @@ -154,6 +155,7 @@ export class Coinbase {
Coinbase.apiClients.balanceHistory = BalanceHistoryApiFactory(config, basePath, axiosInstance);
Coinbase.apiClients.contractEvent = ContractEventsApiFactory(config, basePath, axiosInstance);
Coinbase.apiClients.smartContract = SmartContractsApiFactory(config, basePath, axiosInstance);
Coinbase.apiClients.fund = FundApiFactory(config, basePath, axiosInstance);
Coinbase.apiClients.transactionHistory = TransactionHistoryApiFactory(
config,
basePath,
Expand Down
99 changes: 99 additions & 0 deletions src/coinbase/crypto_amount.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
import Decimal from "decimal.js";
import { CryptoAmount as CryptoAmountModel } from "../client/api";
import { Asset } from "./asset";

/**
* A representation of a CryptoAmount that includes the amount and asset.
*/
export class CryptoAmount {
private amount: Decimal;
private assetObj: Asset;
private assetId: string;

/**
* Creates a new CryptoAmount instance.
*
* @param amount - The amount of the Asset
* @param asset - The Asset
* @param assetId - Optional Asset ID override
*/
constructor(amount: Decimal, asset: Asset, assetId?: string) {
this.amount = amount;
this.assetObj = asset;
this.assetId = assetId || asset.getAssetId();
}

/**
* Converts a CryptoAmount model to a CryptoAmount.
*
* @param amountModel - The crypto amount from the API
* @returns The converted CryptoAmount object
*/
public static fromModel(amountModel: CryptoAmountModel): CryptoAmount {
const asset = Asset.fromModel(amountModel.asset);
return new CryptoAmount(asset.fromAtomicAmount(new Decimal(amountModel.amount)), asset);
}

/**
* Converts a CryptoAmount model and asset ID to a CryptoAmount.
* This can be used to specify a non-primary denomination that we want the amount
* to be converted to.
*
* @param amountModel - The crypto amount from the API
* @param assetId - The Asset ID of the denomination we want returned
* @returns The converted CryptoAmount object
*/
public static fromModelAndAssetId(amountModel: CryptoAmountModel, assetId: string): CryptoAmount {
const asset = Asset.fromModel(amountModel.asset, assetId);
return new CryptoAmount(
asset.fromAtomicAmount(new Decimal(amountModel.amount)),
asset,
assetId,
);
}

/**
* Gets the amount of the Asset.
*
* @returns The amount of the Asset
*/
public getAmount(): Decimal {
return this.amount;
}

/**
* Gets the Asset.
*
* @returns The Asset
*/
public getAsset(): Asset {
return this.assetObj;
}

/**
* Gets the Asset ID.
*
* @returns The Asset ID
*/
public getAssetId(): string {
return this.assetId;
}

/**
* Converts the amount to atomic units.
*
* @returns The amount in atomic units
*/
public toAtomicAmount(): bigint {
return this.assetObj.toAtomicAmount(this.amount);
}

/**
* Returns a string representation of the CryptoAmount.
*
* @returns A string representation of the CryptoAmount
*/
public toString(): string {
return `CryptoAmount{amount: '${this.amount}', assetId: '${this.assetId}'}`;
}
}
57 changes: 57 additions & 0 deletions src/coinbase/fiat_amount.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import { FiatAmount as FiatAmountModel } from "../client/api";

/**
* A representation of a FiatAmount that includes the amount and currency.
*/
export class FiatAmount {
private amount: string;
private currency: string;

/**
* Initialize a new FiatAmount. Do not use this directly, use the fromModel method instead.
*
* @param amount - The amount in the fiat currency
* @param currency - The currency code (e.g. 'USD')
*/
constructor(amount: string, currency: string) {
this.amount = amount;
this.currency = currency;
}

/**
* Convert a FiatAmount model to a FiatAmount.
*
* @param fiatAmountModel - The fiat amount from the API.
* @returns The converted FiatAmount object.
*/
public static fromModel(fiatAmountModel: FiatAmountModel): FiatAmount {
return new FiatAmount(fiatAmountModel.amount, fiatAmountModel.currency);
}

/**
* Get the amount in the fiat currency.
*
* @returns The amount in the fiat currency.
*/
public getAmount(): string {
return this.amount;
}

/**
* Get the currency code.
*
* @returns The currency code.
*/
public getCurrency(): string {
return this.currency;
}

/**
* Get a string representation of the FiatAmount.
*
* @returns A string representation of the FiatAmount.
*/
public toString(): string {
return `FiatAmount(amount: '${this.amount}', currency: '${this.currency}')`;
}
}
Loading