Skip to content

Commit

Permalink
headless: update plugin (#317)
Browse files Browse the repository at this point in the history
* save

* lock

* imp

* lint

* changeset
  • Loading branch information
mPaella authored Feb 7, 2025
1 parent fb76f39 commit ca7611b
Show file tree
Hide file tree
Showing 6 changed files with 90 additions and 37 deletions.
1 change: 0 additions & 1 deletion biome.json

This file was deleted.

5 changes: 5 additions & 0 deletions typescript/.changeset/strong-owls-hug.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@goat-sdk/plugin-crossmint-headless-checkout": patch
---

headless: tweak plugin
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"dependencies": {
"@goat-sdk/core": "workspace:*",
"@crossmint/common-sdk-base": "0.3.1",
"@crossmint/client-sdk-base": "1.4.4",
"@crossmint/client-sdk-base": "1.4.6",
"@goat-sdk/wallet-evm": "workspace:*",
"viem": "catalog:",
"zod": "catalog:"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export class CrossmintHeadlessCheckoutPlugin extends PluginBase {

constructor(
private readonly crossmint: Crossmint,
private readonly callDataSchema: z.ZodSchema,
private readonly callDataSchema?: z.ZodSchema,
) {
super("crossmint-headless-checkout", []);

Expand All @@ -32,7 +32,7 @@ export class CrossmintHeadlessCheckoutPlugin extends PluginBase {
}

supportsChain(chain: Chain): boolean {
return chain.type === "evm"; // TODO: Add support for more blockchains
return true;
}

async getTools(walletClient: EVMWalletClient) {
Expand Down Expand Up @@ -65,7 +65,10 @@ export class CrossmintHeadlessCheckoutPlugin extends PluginBase {
throw new Error(errorMessage);
}

const { order } = (await res.json()) as { order: Order; orderClientSecret: string };
const { order } = (await res.json()) as {
order: Order;
orderClientSecret: string;
};

console.log("Created order:", order.orderId);

Expand All @@ -74,13 +77,22 @@ export class CrossmintHeadlessCheckoutPlugin extends PluginBase {
throw new Error("Insufficient funds");
}

const isRequiresPhysicalAddress = order.quote.status === "requires-physical-address";
if (isRequiresPhysicalAddress) {
throw new Error("recipient.physicalAddress is required");
}

const serializedTransaction =
order.payment.preparation != null && "serializedTransaction" in order.payment.preparation
? order.payment.preparation.serializedTransaction
: undefined;
if (!serializedTransaction) {
throw new Error(
`No serialized transaction found for order, this item may not be available for purchase:\n\n ${JSON.stringify(order, null, 2)}`,
`No serialized transaction found for order, this item may not be available for purchase:\n\n ${JSON.stringify(
order,
null,
2,
)}`,
);
}

Expand All @@ -104,6 +116,6 @@ export class CrossmintHeadlessCheckoutPlugin extends PluginBase {
}
}

export const crossmintHeadlessCheckout = (crossmint: Crossmint, callDataSchema: z.ZodSchema) => {
export const crossmintHeadlessCheckout = (crossmint: Crossmint, callDataSchema?: z.ZodSchema) => {
return new CrossmintHeadlessCheckoutPlugin(crossmint, callDataSchema);
};
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,17 @@ import { z } from "zod";
* @param callDataSchema - Schema for contract-specific call data validation
* @returns Zod schema object defining the structure of order parameters
*/
export function getCreateAndPayOrderParameters(callDataSchema: z.ZodSchema) {
export function getCreateAndPayOrderParameters(callDataSchema?: z.ZodSchema) {
return z.object({
recipient: z
.union([
z.object({
walletAddress: z.string(),
physicalAddress: physicalAddressSchema.optional(),
}),
z.object({
email: z.string().email(),
physicalAddress: physicalAddressSchema.optional(),
}),
])
.describe(
Expand All @@ -33,15 +35,57 @@ export function getCreateAndPayOrderParameters(callDataSchema: z.ZodSchema) {
),
lineItems: z
.array(
z.object({
collectionLocator: z
.string()
.describe(
"The collection locator. Ex: 'crossmint:<crossmint_collection_id>', '<chain>:<contract_address>'",
), // TODO: Add tokenLocator support
callData: callDataSchema,
}),
// TODO: Add tokenLocator support
z.union([
z.object({
collectionLocator: z
.string()
.describe(
"The collection locator. Ex: 'crossmint:<crossmint_collection_id>', '<chain>:<contract_address>'",
),
...(callDataSchema ? { callData: callDataSchema } : {}),
}),
z.object({
productLocator: z
.string()
.describe("The product locator. Ex: 'amazon:<amazon_product_id>', 'amazon:<asin>'"),
...(callDataSchema ? { callData: callDataSchema } : {}),
}),
]),
)
.describe("Array of items to purchase"),
});
}

export const physicalAddressSchema = z
.object({
name: z.string().min(1, "Name is required for physical address"),
line1: z.string().min(1, "Line 1 is required for physical address"),
line2: z.string().optional(),
city: z.string().min(1, "City is required for physical address"),

state: z.string().optional().describe("State/Province/Region - optional"),
postalCode: z.string().min(1, "Postal/ZIP code is required for physical address"),
country: z
.string()
.min(2, "Country is required for physical address")
.max(2, "Country must be a 2-letter ISO code for physical address")
.toUpperCase(),
})
.superRefine((data, ctx) => {
// TODO: allow more countries
if (data.country !== "US") {
ctx.addIssue({
code: z.ZodIssueCode.custom,
message: "Only 'US' country code is supported at this time",
});
}

if (data.country === "US" && !data.state) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
message: "State is required for US physical address",
});
}
})
.describe("International mailing address using ISO 3166-1 alpha-2 country codes");
35 changes: 14 additions & 21 deletions typescript/pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit ca7611b

Please sign in to comment.