Skip to content

Commit

Permalink
📝 Cleaner documentation around the interactions
Browse files Browse the repository at this point in the history
  • Loading branch information
KONFeature committed Dec 12, 2024
1 parent 4e0fb11 commit 5f076df
Show file tree
Hide file tree
Showing 15 changed files with 200 additions and 115 deletions.
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -54,4 +54,6 @@ packages/wallet/next-env.d.ts
.idea

# Turbo tmp stuff
.turbo
.turbo

generated-docs/
Binary file modified bun.lockb
Binary file not shown.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
"rimraf": "^6.0.1",
"sst": "3.3.28",
"typedoc": "^0.27.4",
"typedoc-plugin-inline-sources": "^1.2.0",
"typedoc-plugin-markdown": "^4.3.2",
"typescript": "^5.6.2"
},
Expand Down
70 changes: 40 additions & 30 deletions sdk/core/src/interactions/pressEncoder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,36 +4,46 @@ import { productTypes } from "../constants/productTypes";
import type { PreparedInteraction } from "../types";

/**
* Encode an open article interaction
* @param articleId
* Press interactions allow you to track user engagement with articles or other press content on your platform.
* After setting up these interactions, you can create acquisition campaign based on the user engagement with your press content.
*
* <Callout type="info">
* To properly handle press interactions, ensure that the "Press" product type is enabled in your Business dashboard.
* </Callout>
*
* {@link PreparedInteraction} The prepared interaction object that can be sent
* @category Interactions Encoder
*
* @see {@link sendInteraction} Action used to send the prepared interaction to the Frak Wallet.
*/
function openArticle({ articleId }: { articleId: Hex }): PreparedInteraction {
const interactionData = concatHex([
interactionTypes.press.openArticle,
pad(articleId, { size: 32 }),
]);
return {
handlerTypeDenominator: toHex(productTypes.press),
interactionData,
};
}

/**
* Encode a read article interaction
* @param articleId
*/
function readArticle({ articleId }: { articleId: Hex }): PreparedInteraction {
const interactionData = concatHex([
interactionTypes.press.readArticle,
pad(articleId, { size: 32 }),
]);
return {
handlerTypeDenominator: toHex(productTypes.press),
interactionData,
};
}

export const PressInteractionEncoder = {
openArticle,
readArticle,
/**
* Encode an open article interaction
* @param articleId The id of the article the user opened (32 bytes), could be a `keccak256` hash of the article slug, or your internal id
*/
openArticle({ articleId }: { articleId: Hex }): PreparedInteraction {
const interactionData = concatHex([
interactionTypes.press.openArticle,
pad(articleId, { size: 32 }),
]);
return {
handlerTypeDenominator: toHex(productTypes.press),
interactionData,
};
},

/**
* Encode a read article interaction
* @param articleId The id of the article the user opened (32 bytes), could be a `keccak256` hash of the article slug, or your internal id
*/
readArticle({ articleId }: { articleId: Hex }): PreparedInteraction {
const interactionData = concatHex([
interactionTypes.press.readArticle,
pad(articleId, { size: 32 }),
]);
return {
handlerTypeDenominator: toHex(productTypes.press),
interactionData,
};
},
};
101 changes: 64 additions & 37 deletions sdk/core/src/interactions/purchaseEncoder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,43 +4,70 @@ import { productTypes } from "../constants/productTypes";
import type { PreparedInteraction } from "../types";

/**
* Encode a start purchase interaction
* Purchase interactions allow you to track user purchases on your platform.
* After setting up these interactions, you can create acquisition campaign based on the user purchase (starting a new one, completed, or even purchase dropped).
*
* <Callout type="info">
* To properly handle purchase interactions, ensure that the "Purchase" product type is enabled in your Business dashboard, and that you have set up everything correctly in the `Purchasetracker` section.
* </Callout>
*
* <Callout type="note">
* The `purchaseId` is used on both interactions. It can be computed like this:
*
* ```ts
* const purchaseId = keccak256(concatHex([productId, toHex(externalPurchaseId)]));
* ```
*
* With:
* - `productId`: The id of your product, you can find it in the product dashboard.
* - `externalPurchaseId`: The id of the purchase in your system (e.g. the shopify `order_id`).
* </Callout>
*
*
* {@link PreparedInteraction} The prepared interaction object that can be sent
* @category Interactions Encoder
*
* @see {@link sendInteraction} Action used to send the prepared interaction to the Frak Wallet.
* @see {@link trackPurchaseStatus} Action that will automatically send the purchase upon completion
* @see [Purchase Webhooks](/wallet-sdk/api-endpoints/webhook) Webhooks to be implemented on your side to confirm a purchase
* @see [Purchase Proof](/wallet-sdk/api-endpoints/purchaseProof) Get a merklee proof for the purchase
*/
function startPurchase({
purchaseId,
}: { purchaseId: Hex }): PreparedInteraction {
const interactionData = concatHex([
interactionTypes.purchase.started,
pad(purchaseId, { size: 32 }),
]);
return {
handlerTypeDenominator: toHex(productTypes.purchase),
interactionData,
};
}

/**
* Encode a complete purchase interaction
*/
function completedPurchase({
purchaseId,
proof,
}: { purchaseId: Hex; proof: Hex[] }): PreparedInteraction {
const innerData = encodeAbiParameters(
[{ type: "uint256" }, { type: "bytes32[]" }],
[BigInt(purchaseId), proof]
);
const interactionData = concatHex([
interactionTypes.purchase.completed,
innerData,
]);
return {
handlerTypeDenominator: toHex(productTypes.purchase),
interactionData,
};
}

export const PurchaseInteractionEncoder = {
startPurchase,
completedPurchase,
/**
* Encode a start purchase interaction
* @param purchaseId The id of the purchase that is being started.
*/
startPurchase({ purchaseId }: { purchaseId: Hex }): PreparedInteraction {
const interactionData = concatHex([
interactionTypes.purchase.started,
pad(purchaseId, { size: 32 }),
]);
return {
handlerTypeDenominator: toHex(productTypes.purchase),
interactionData,
};
},

/**
* Encode a complete purchase interaction
* @param purchaseId The id of the purchase that is being completed.
* @param proof The merkle proof that the user has completed the purchase (see [Purchase Webhooks](/wallet-sdk/api-endpoints/webhook) for more details).
*/
completedPurchase({
purchaseId,
proof,
}: { purchaseId: Hex; proof: Hex[] }): PreparedInteraction {
const innerData = encodeAbiParameters(
[{ type: "uint256" }, { type: "bytes32[]" }],
[BigInt(purchaseId), proof]
);
const interactionData = concatHex([
interactionTypes.purchase.completed,
innerData,
]);
return {
handlerTypeDenominator: toHex(productTypes.purchase),
interactionData,
};
},
};
68 changes: 39 additions & 29 deletions sdk/core/src/interactions/referralEncoder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,35 +4,45 @@ import { productTypes } from "../constants/productTypes";
import type { PreparedInteraction } from "../types";

/**
* Encode a create referral link interaction
* Referral interactions allow you to track user sharing activities.
* These interactions are essential for platforms looking to grow their user base through user-to-user referrals and reward systems.
*
* <Callout type="info">
* To properly handle referral interactions, ensure that the "Referral" product type is enabled in your Business dashboard.
* </Callout>
*
* {@link PreparedInteraction} The prepared interaction object that can be sent
* @category Interactions Encoder
*
* @see {@link sendInteraction} Action used to send the prepared interaction to the Frak Wallet.
*/
function createLink(): PreparedInteraction {
const interactionData = concatHex([
interactionTypes.referral.createLink,
"0x",
]);
return {
handlerTypeDenominator: toHex(productTypes.referral),
interactionData,
};
}

/**
* Encode a referred interaction
* @param referrer
*/
function referred({ referrer }: { referrer: Address }): PreparedInteraction {
const interactionData = concatHex([
interactionTypes.referral.referred,
pad(referrer, { size: 32 }),
]);
return {
handlerTypeDenominator: toHex(productTypes.referral),
interactionData,
};
}

export const ReferralInteractionEncoder = {
createLink,
referred,
/**
* Records the event of a user creating a referral link. Note that this interaction doesn't actually create the link itself; it only sends an event to track that a link was created.
*/
createLink(): PreparedInteraction {
const interactionData = concatHex([
interactionTypes.referral.createLink,
"0x",
]);
return {
handlerTypeDenominator: toHex(productTypes.referral),
interactionData,
};
},

/**
* Encode a referred interaction
* @param referrer The Ethereum address of the user who made the referral
*/
referred({ referrer }: { referrer: Address }): PreparedInteraction {
const interactionData = concatHex([
interactionTypes.referral.referred,
pad(referrer, { size: 32 }),
]);
return {
handlerTypeDenominator: toHex(productTypes.referral),
interactionData,
};
},
};
33 changes: 23 additions & 10 deletions sdk/core/src/interactions/webshopEncoder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,29 @@ import { productTypes } from "../constants/productTypes";
import type { PreparedInteraction } from "../types";

/**
* Encode a create referral link interaction
* Webshop interactions allow you to track user activities on your webshop.
*
* <Callout type="info">
* To properly handle webshop interactions, ensure that the "WebShop" product type is enabled in your Business dashboard.
* </Callout>
*
* {@link PreparedInteraction} The prepared interaction object that can be sent
* @category Interactions Encoder
*
* @see {@link sendInteraction} Action used to send the prepared interaction to the Frak Wallet.
*/
function open(): PreparedInteraction {
const interactionData = concatHex([interactionTypes.webshop.open, "0x"]);
return {
handlerTypeDenominator: toHex(productTypes.webshop),
interactionData,
};
}

export const WebShopInteractionEncoder = {
open,
/**
* Encode an open webshop interaction
*/
open(): PreparedInteraction {
const interactionData = concatHex([
interactionTypes.webshop.open,
"0x",
]);
return {
handlerTypeDenominator: toHex(productTypes.webshop),
interactionData,
};
},
};
3 changes: 3 additions & 0 deletions sdk/core/src/types/compression.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/**
* The received encoded data from a client
* -> The encoded should contain a HashProtectedData once decoded
* @ignore
*/
export type CompressedData = Readonly<{
compressed: string;
Expand All @@ -9,6 +10,7 @@ export type CompressedData = Readonly<{

/**
* The encoded data to send to a client / received by a client
* @ignore
*/
export type HashProtectedData<DataType> = Readonly<
DataType & {
Expand All @@ -18,5 +20,6 @@ export type HashProtectedData<DataType> = Readonly<

/**
* Represent a key provider used for the hashed and secure compression
* @ignore
*/
export type KeyProvider<DataType> = (value: DataType) => string[];
6 changes: 5 additions & 1 deletion sdk/core/src/types/rpc/error.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/**
* Generic Frak RPC error
* @ignore
*/
export class FrakRpcError<T = undefined> extends Error {
constructor(
Expand All @@ -11,26 +12,29 @@ export class FrakRpcError<T = undefined> extends Error {
}
}

/** @ignore */
export class MethodNotFoundError extends FrakRpcError<{ method: string }> {
constructor(message: string, method: string) {
super(RpcErrorCodes.methodNotFound, message, { method });
}
}

/** @ignore */
export class InternalError extends FrakRpcError {
constructor(message: string) {
super(RpcErrorCodes.internalError, message);
}
}

/** @ignore */
export class ClientNotFound extends FrakRpcError {
constructor() {
super(RpcErrorCodes.clientNotConnected, "Client not found");
}
}

/**
* All the rpc error codes
* The different Frak RPC error codes
*/
export const RpcErrorCodes = {
// Standard JSON-RPC 2.0 errors
Expand Down
4 changes: 4 additions & 0 deletions sdk/core/src/utils/Deferred.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
/**
* Simple deferred promise wrapper
* @ignore
*/
export class Deferred<T> {
private readonly _promise: Promise<T>;
private _resolve: ((value: T | PromiseLike<T>) => void) | undefined;
Expand Down
Loading

0 comments on commit 5f076df

Please sign in to comment.