Skip to content

Commit

Permalink
dev: add DaimoPayToken
Browse files Browse the repository at this point in the history
  • Loading branch information
dcposch committed Sep 30, 2024
1 parent eb75817 commit 0163af4
Show file tree
Hide file tree
Showing 8 changed files with 1,321 additions and 5 deletions.
6 changes: 3 additions & 3 deletions packages/daimo-common/package.json
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
{
"name": "@daimo/common",
"version": "0.2.10",
"description": "Shared between web and mobile",
"description": "Daimo shared models and utilities",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"author": "",
"license": "MIT",
"scripts": {
"build": "tsc",
"test": "tape -r ts-node/register/transpile-only test/**/*.test.ts",
"lint": "npm run lint:deps && npm run lint:style",
"lint:deps": "npx depcheck --ignores @tsconfig/node20,@types/tape,ts-node",
"lint:style": "eslint . --max-warnings=0"
},
"author": "",
"license": "GPL-3.0-or-later",
"devDependencies": {
"@tsconfig/node20": "^20.1.4",
"@types/tape": "^5.6.0",
Expand Down
51 changes: 51 additions & 0 deletions packages/daimo-common/src/chainExplorer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { Address, Hex } from "viem";

/**
* Get block explorer URL for chain ID
*/
export function getChainExplorerByChainId(chainId: number): string | undefined {
switch (chainId) {
case 1:
return "https://etherscan.io";
case 8453:
return "https://basescan.org";
case 42161:
return "https://arbiscan.io";
case 10:
return "https://optimistic.etherscan.io";
case 137:
return "https://polygonscan.com";
case 43114:
return "https://snowtrace.io";
case 11155111:
return "https://sepolia.etherscan.io";
case 84532:
return "https://sepolia.basescan.org";
case 421614:
return "https://sepolia.arbiscan.io";
case 11155420:
return "https://sepolia-optimism.etherscan.io";
case 80002:
return "https://amoy.polygonscan.com";
case 43113:
return "https://testnet.snowtrace.io";
default:
return undefined;
}
}

export function getChainExplorerAddressUrl(chainId: number, address: Address) {
const explorer = getChainExplorerByChainId(chainId);
if (!explorer) {
return undefined;
}
return `${explorer}/address/${address}`;
}

export function getChainExplorerTxUrl(chainId: number, txHash: Hex) {
const explorer = getChainExplorerByChainId(chainId);
if (!explorer) {
return undefined;
}
return `${explorer}/tx/${txHash}`;
}
122 changes: 122 additions & 0 deletions packages/daimo-common/src/daimoPay.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
import { ForeignToken } from "@daimo/contract";
import { base58 } from "@scure/base";
import { Address, bytesToBigInt, Hex, numberToBytes, zeroAddress } from "viem";

import { BigIntStr } from "./model";

// lifecycle: waiting payment -> processed.
export enum DaimoPayOrderStatusSource {
WAITING_PAYMENT = "waiting_payment",
PENDING_PROCESSING = "pending_processing",
PROCESSED = "processed",
}

// lifecycle: pending -> fast-finished (optionally) -> claimed
export enum DaimoPayOrderStatusDest {
PENDING = "pending",
FAST_FINISHED = "fast_finished",
CLAIMED = "claimed",
}

export enum DaimoPayOrderMode {
SALE = "sale", // product or item sale
CHOOSE_AMOUNT = "choose_amount", // let the user specify the amount to pay
HYDRATED = "hydrated", // once hydrated, the order is final and all parameters are known and immutable
}

export interface DaimoPayOrderItem {
name: string;
description: string;
image: string;
}

export type DaimoPayDehydratedOrder = {
mode: DaimoPayOrderMode.SALE | DaimoPayOrderMode.CHOOSE_AMOUNT;
id: bigint;
destFinalCallTokenAmount: DaimoPayTokenAmount;
destFinalCall: OnChainCall;
destNonce: bigint;
intent: string;
itemsJson: string | null;
redirectUri: string | null;
};

export type DaimoPayHydratedOrder = {
mode: DaimoPayOrderMode.HYDRATED;
id: bigint;
handoffAddr: Address;
destMintTokenAmount: DaimoPayTokenAmount;
destFinalCallTokenAmount: DaimoPayTokenAmount;
destFinalCall: OnChainCall;
destRefundAddr: Address;
destNonce: bigint;
sourceTokenAmount: DaimoPayTokenAmount | null;
sourceInitiateTxHash: Hex | null;
sourceStartTxHash: Hex | null;
sourceStatus: DaimoPayOrderStatusSource;
destStatus: DaimoPayOrderStatusDest;
destFastFinishTxHash: Hex | null;
destClaimTxHash: Hex | null;
intent: string;
itemsJson: string | null;
redirectUri: string | null;
};

export type DaimoPayHydratedOrderWithoutHandoffAddr = Omit<
DaimoPayHydratedOrder,
"handoffAddr"
>;

export type DaimoPayOrder = DaimoPayDehydratedOrder | DaimoPayHydratedOrder;

export type ExternalPaymentOptionMetadata = {
id: ExternalPaymentOptions;
cta: string;
logoURI: string;
paymentToken: DaimoPayToken;
};

export type ExternalPaymentOptionData = {
url: string;
waitingMessage: string;
};

export enum ExternalPaymentOptions {
Daimo = "Daimo",
Coinbase = "Coinbase",
RampNetwork = "RampNetwork",
}

export interface DaimoPayToken extends ForeignToken {
usd: number; // per unit price in dollars, example 2300 (USD) for WETH
quoteTimestamp: number;
quoteBlockNumber: number;
displayDecimals: number; // TODO, human friendly number of decimals for the token
fiatSymbol?: string; // e.g. $ for USDC/USDT/DAI, € for EUROC, etc
}

export interface DaimoPayTokenAmount {
token: DaimoPayToken;
amount: BigIntStr;
usd: number; // amount in dollars
}

export type OnChainCall = {
to: Address;
data: Hex;
value: bigint;
};

export const emptyOnChainCall: OnChainCall = {
to: zeroAddress,
data: "0x",
value: 0n,
};

export function readEncodedDaimoPayID(id: string): bigint {
return bytesToBigInt(base58.decode(id));
}

export function writeEncodedDaimoPayID(id: bigint): string {
return base58.encode(numberToBytes(id));
}
2 changes: 2 additions & 0 deletions packages/daimo-common/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,5 @@ export * from "./sendPair";
export * from "./time";
export * from "./viemClient";
export * from "./moneyEntry";
export * from "./daimoPay";
export * from "./chainExplorer";
Loading

0 comments on commit 0163af4

Please sign in to comment.