UNPKG

@coinbase/cdp-sdk

Version:

SDK for interacting with the Coinbase Developer Platform Wallet API

657 lines 26.1 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.EndUserClient = void 0; const crypto_1 = require("crypto"); const bs58_1 = __importDefault(require("bs58")); const toEndUserAccount_js_1 = require("./toEndUserAccount.js"); const analytics_js_1 = require("../../analytics.js"); const constants_js_1 = require("../../constants.js"); const errors_js_1 = require("../../errors.js"); const index_js_1 = require("../../openapi-client/index.js"); /** * The CDP end user client. */ class EndUserClient { /** * Creates an end user. An end user is an entity that can own CDP EVM accounts, * EVM smart accounts, and/or Solana accounts. * * @param options - The options for creating an end user. * * @returns A promise that resolves to the created end user. * * @example **Create an end user with an email authentication method** * ```ts * const endUser = await cdp.endUser.createEndUser({ * authenticationMethods: [ * { type: "email", email: "user@example.com" } * ] * }); * console.log(endUser.userId); * ``` * * @example **Create an end user with an EVM EOA account** * ```ts * const endUser = await cdp.endUser.createEndUser({ * authenticationMethods: [ * { type: "email", email: "user@example.com" } * ], * evmAccount: { createSmartAccount: false } * }); * ``` */ async createEndUser(options) { analytics_js_1.Analytics.trackAction({ action: "create_end_user", }); const userId = options.userId ?? (0, crypto_1.randomUUID)(); const endUser = await index_js_1.CdpOpenApiClient.createEndUser({ ...options, userId, }, options.idempotencyKey); return (0, toEndUserAccount_js_1.toEndUserAccount)(index_js_1.CdpOpenApiClient, { endUser }); } /** * Lists end users belonging to the developer's CDP Project. * By default, the response is sorted by creation date in ascending order and paginated to 20 users per page. * * @param options - The options for listing end users. * * @returns A promise that resolves to a paginated list of end users. * * @example **List all end users** * ```ts * const result = await cdp.endUsers.listEndUsers(); * console.log(result.endUsers); * ``` * * @example **With pagination** * ```ts * let page = await cdp.endUsers.listEndUsers({ pageSize: 10 }); * * while (page.nextPageToken) { * page = await cdp.endUsers.listEndUsers({ * pageSize: 10, * pageToken: page.nextPageToken * }); * } * ``` * * @example **With sorting** * ```ts * const result = await cdp.endUsers.listEndUsers({ * sort: ['createdAt=desc'] * }); * ``` */ async listEndUsers(options = {}) { analytics_js_1.Analytics.trackAction({ action: "list_end_users", }); const params = { ...options, ...(options.sort && { sort: options.sort.join(",") }), }; return index_js_1.CdpOpenApiClient.listEndUsers(params); } /** * Gets an end user by their unique identifier. * * @param options - The options for getting an end user. * * @returns A promise that resolves to the end user. * * @example **Get an end user by ID** * ```ts * const endUser = await cdp.endUser.getEndUser({ * userId: "user-123" * }); * console.log(endUser.userId); * ``` */ async getEndUser(options) { analytics_js_1.Analytics.trackAction({ action: "get_end_user", }); const { userId } = options; const endUser = await index_js_1.CdpOpenApiClient.getEndUser(userId); return (0, toEndUserAccount_js_1.toEndUserAccount)(index_js_1.CdpOpenApiClient, { endUser }); } /** * Adds an EVM EOA (Externally Owned Account) to an existing end user. End users can have up to 10 EVM accounts. * * @param options - The options for adding an EVM account. * * @returns A promise that resolves to the newly created EVM EOA account. * * @example **Add an EVM EOA account to an existing end user** * ```ts * const result = await cdp.endUser.addEndUserEvmAccount({ * userId: "user-123" * }); * console.log(result.evmAccount.address); * ``` */ async addEndUserEvmAccount(options) { analytics_js_1.Analytics.trackAction({ action: "add_end_user_evm_account", }); const { userId, idempotencyKey } = options; return index_js_1.CdpOpenApiClient.addEndUserEvmAccount(userId, {}, idempotencyKey); } /** * Adds an EVM smart account to an existing end user. This also creates a new EVM EOA account to serve as the owner of the smart account. * * @param options - The options for adding an EVM smart account. * * @returns A promise that resolves to the newly created EVM smart account. * * @example **Add an EVM smart account to an existing end user** * ```ts * const result = await cdp.endUser.addEndUserEvmSmartAccount({ * userId: "user-123", * enableSpendPermissions: false * }); * console.log(result.evmSmartAccount.address); * ``` * * @example **Add an EVM smart account with spend permissions enabled** * ```ts * const result = await cdp.endUser.addEndUserEvmSmartAccount({ * userId: "user-123", * enableSpendPermissions: true * }); * console.log(result.evmSmartAccount.address); * ``` */ async addEndUserEvmSmartAccount(options) { analytics_js_1.Analytics.trackAction({ action: "add_end_user_evm_smart_account", }); const { userId, enableSpendPermissions, idempotencyKey } = options; return index_js_1.CdpOpenApiClient.addEndUserEvmSmartAccount(userId, { enableSpendPermissions }, idempotencyKey); } /** * Adds a Solana account to an existing end user. End users can have up to 10 Solana accounts. * * @param options - The options for adding a Solana account. * * @returns A promise that resolves to the newly created Solana account. * * @example **Add a Solana account to an existing end user** * ```ts * const result = await cdp.endUser.addEndUserSolanaAccount({ * userId: "user-123" * }); * console.log(result.solanaAccount.address); * ``` */ async addEndUserSolanaAccount(options) { analytics_js_1.Analytics.trackAction({ action: "add_end_user_solana_account", }); const { userId, idempotencyKey } = options; return index_js_1.CdpOpenApiClient.addEndUserSolanaAccount(userId, {}, idempotencyKey); } /** * Gets the active delegation for the specified end user, if one exists. * This operation can be performed by the end user themselves or by a developer using their API key. * * @param options - The options for getting the delegation. * * @returns A promise that resolves to the delegation details including its expiry. * * @example **Get the active delegation for an end user** * ```ts * const delegation = await cdp.endUser.getDelegationForEndUser({ * userId: "user-123" * }); * console.log(delegation.expiresAt); * ``` */ async getDelegationForEndUser(options) { analytics_js_1.Analytics.trackAction({ action: "get_delegation_for_end_user", }); const { userId } = options; return index_js_1.CdpOpenApiClient.getDelegationForEndUser(userId); } /** * Revokes all active delegations for the specified end user. * This operation can be performed by the end user themselves or by a developer using their API key. * * @param options - The options for revoking the delegation. * * @returns A promise that resolves when the delegation has been revoked. * * @example **Revoke all delegations for an end user** * ```ts * await cdp.endUser.revokeDelegationForEndUser({ * userId: "user-123" * }); * ``` */ async revokeDelegationForEndUser(options) { analytics_js_1.Analytics.trackAction({ action: "revoke_delegation_for_end_user", }); const { userId, idempotencyKey } = options; await index_js_1.CdpOpenApiClient.revokeDelegationForEndUser(userId, {}, undefined, idempotencyKey); } // ─── Account-Scoped Delegation Methods ─── /** * Gets the active account-scoped delegation for the specified end user account address, if one exists. * * @param options - The options for getting the account-scoped delegation. * * @returns A promise that resolves to the delegation details including its expiry. * * @example **Get the account-scoped delegation for an address** * ```ts * const delegation = await cdp.endUser.getDelegationForEndUserAccount({ * userId: "user-123", * address: "0x1234...", * }); * console.log(delegation.expiresAt); * ``` */ async getDelegationForEndUserAccount(options) { analytics_js_1.Analytics.trackAction({ action: "get_delegation_for_end_user_account", }); const { userId, address } = options; return index_js_1.CdpOpenApiClient.getDelegationForEndUserAccount(userId, address); } /** * Revokes the active account-scoped delegation for the specified end user account address. * Other account-scoped delegations for the same user are unaffected. * * @param options - The options for revoking the account-scoped delegation. * * @returns A promise that resolves when the delegation has been revoked. * * @example **Revoke the account-scoped delegation for an address** * ```ts * await cdp.endUser.revokeDelegationForEndUserAccount({ * userId: "user-123", * address: "0x1234...", * }); * ``` */ async revokeDelegationForEndUserAccount(options) { analytics_js_1.Analytics.trackAction({ action: "revoke_delegation_for_end_user_account", }); const { userId, address, idempotencyKey } = options; await index_js_1.CdpOpenApiClient.revokeDelegationForEndUserAccount(userId, address, {}, undefined, idempotencyKey); } // ─── Delegated EVM Sign Methods ─── /** * Signs an EVM transaction on behalf of an end user using a delegation. * * @param options - The options for signing an EVM transaction. * * @returns A promise that resolves to the signed transaction. * * @example * ```ts * const result = await cdp.endUser.signEvmTransaction({ * userId: "user-123", * address: "0x1234...", * transaction: "0x02..." * }); * console.log(result.signedTransaction); * ``` */ async signEvmTransaction(options) { analytics_js_1.Analytics.trackAction({ action: "end_user_sign_evm_transaction" }); return index_js_1.CdpOpenApiClient.signEvmTransactionWithEndUserAccount(options.userId, { address: options.address, transaction: options.transaction }, undefined, options.idempotencyKey); } /** * Signs an EVM message (EIP-191) on behalf of an end user using a delegation. * * @param options - The options for signing an EVM message. * * @returns A promise that resolves to the signature. * * @example * ```ts * const result = await cdp.endUser.signEvmMessage({ * userId: "user-123", * address: "0x1234...", * message: "Hello, World!" * }); * console.log(result.signature); * ``` */ async signEvmMessage(options) { analytics_js_1.Analytics.trackAction({ action: "end_user_sign_evm_message" }); return index_js_1.CdpOpenApiClient.signEvmMessageWithEndUserAccount(options.userId, { address: options.address, message: options.message }, undefined, options.idempotencyKey); } /** * Signs EVM EIP-712 typed data on behalf of an end user using a delegation. * * @param options - The options for signing EVM typed data. * * @returns A promise that resolves to the signature. * * @example * ```ts * const result = await cdp.endUser.signEvmTypedData({ * userId: "user-123", * address: "0x1234...", * typedData: { domain: {}, types: {}, primaryType: "...", message: {} } * }); * console.log(result.signature); * ``` */ async signEvmTypedData(options) { analytics_js_1.Analytics.trackAction({ action: "end_user_sign_evm_typed_data" }); return index_js_1.CdpOpenApiClient.signEvmTypedDataWithEndUserAccount(options.userId, { address: options.address, typedData: options.typedData }, undefined, options.idempotencyKey); } // ─── Delegated EVM Send Methods ─── /** * Sends an EVM transaction on behalf of an end user using a delegation. * * @param options - The options for sending an EVM transaction. * * @returns A promise that resolves to the transaction hash. * * @example * ```ts * const result = await cdp.endUser.sendEvmTransaction({ * userId: "user-123", * address: "0x1234...", * transaction: "0x02...", * network: "base-sepolia" * }); * console.log(result.transactionHash); * ``` */ async sendEvmTransaction(options) { analytics_js_1.Analytics.trackAction({ action: "end_user_send_evm_transaction" }); return index_js_1.CdpOpenApiClient.sendEvmTransactionWithEndUserAccount(options.userId, { address: options.address, transaction: options.transaction, network: options.network }, undefined, options.idempotencyKey); } /** * Sends an EVM asset (e.g. USDC) on behalf of an end user using a delegation. * * @param options - The options for sending an EVM asset. * * @returns A promise that resolves to the transaction result. * * @example * ```ts * const result = await cdp.endUser.sendEvmAsset({ * userId: "user-123", * address: "0x1234...", * to: "0xabcd...", * amount: "1000000", * network: "base-sepolia" * }); * console.log(result.transactionHash); * ``` */ async sendEvmAsset(options) { analytics_js_1.Analytics.trackAction({ action: "end_user_send_evm_asset" }); const asset = options.asset ?? "usdc"; return index_js_1.CdpOpenApiClient.sendEvmAssetWithEndUserAccount(options.userId, options.address, asset, { to: options.to, amount: options.amount, network: options.network, useCdpPaymaster: options.useCdpPaymaster, paymasterUrl: options.paymasterUrl, }, undefined, options.idempotencyKey); } /** * Sends a user operation on behalf of an end user using a delegation. * * @param options - The options for sending a user operation. * * @returns A promise that resolves to the user operation result. * * @example * ```ts * const result = await cdp.endUser.sendUserOperation({ * userId: "user-123", * address: "0x1234...", * network: "base-sepolia", * calls: [{ to: "0xabcd...", value: "0", data: "0x" }], * useCdpPaymaster: true * }); * ``` */ async sendUserOperation(options) { analytics_js_1.Analytics.trackAction({ action: "end_user_send_user_operation" }); return index_js_1.CdpOpenApiClient.sendUserOperationWithEndUserAccount(options.userId, options.address, { network: options.network, calls: options.calls, useCdpPaymaster: options.useCdpPaymaster, paymasterUrl: options.paymasterUrl, dataSuffix: options.dataSuffix, }, undefined, options.idempotencyKey); } // ─── Delegated EVM EIP-7702 Delegation Method ─── /** * Creates an EVM EIP-7702 delegation on behalf of an end user. * * @param options - The options for creating an EIP-7702 delegation. * * @returns A promise that resolves to the delegation operation ID. * * @example * ```ts * const result = await cdp.endUser.createEvmEip7702Delegation({ * userId: "user-123", * address: "0x1234...", * network: "base-sepolia" * }); * console.log(result.delegationOperationId); * ``` */ async createEvmEip7702Delegation(options) { analytics_js_1.Analytics.trackAction({ action: "end_user_create_evm_eip7702_delegation" }); return index_js_1.CdpOpenApiClient.createEvmEip7702DelegationWithEndUserAccount(options.userId, { address: options.address, network: options.network, enableSpendPermissions: options.enableSpendPermissions, }, undefined, options.idempotencyKey); } // ─── Delegated Solana Sign Methods ─── /** * Signs a Solana message on behalf of an end user using a delegation. * * @param options - The options for signing a Solana message. * * @returns A promise that resolves to the signature. * * @example * ```ts * const result = await cdp.endUser.signSolanaMessage({ * userId: "user-123", * address: "So1ana...", * message: "base64message..." * }); * console.log(result.signature); * ``` */ async signSolanaMessage(options) { analytics_js_1.Analytics.trackAction({ action: "end_user_sign_solana_message" }); return index_js_1.CdpOpenApiClient.signSolanaMessageWithEndUserAccount(options.userId, { address: options.address, message: options.message }, undefined, options.idempotencyKey); } /** * Signs a Solana transaction on behalf of an end user using a delegation. * * @param options - The options for signing a Solana transaction. * * @returns A promise that resolves to the signed transaction. * * @example * ```ts * const result = await cdp.endUser.signSolanaTransaction({ * userId: "user-123", * address: "So1ana...", * transaction: "base64tx..." * }); * console.log(result.signedTransaction); * ``` */ async signSolanaTransaction(options) { analytics_js_1.Analytics.trackAction({ action: "end_user_sign_solana_transaction" }); return index_js_1.CdpOpenApiClient.signSolanaTransactionWithEndUserAccount(options.userId, { address: options.address, transaction: options.transaction }, undefined, options.idempotencyKey); } // ─── Delegated Solana Send Methods ─── /** * Sends a Solana transaction on behalf of an end user using a delegation. * * @param options - The options for sending a Solana transaction. * * @returns A promise that resolves to the transaction signature. * * @example * ```ts * const result = await cdp.endUser.sendSolanaTransaction({ * userId: "user-123", * address: "So1ana...", * transaction: "base64tx...", * network: "solana-devnet" * }); * console.log(result.transactionSignature); * ``` */ async sendSolanaTransaction(options) { analytics_js_1.Analytics.trackAction({ action: "end_user_send_solana_transaction" }); return index_js_1.CdpOpenApiClient.sendSolanaTransactionWithEndUserAccount(options.userId, { address: options.address, transaction: options.transaction, network: options.network, }, undefined, options.idempotencyKey); } /** * Sends a Solana asset (e.g. USDC) on behalf of an end user using a delegation. * * @param options - The options for sending a Solana asset. * * @returns A promise that resolves to the transaction signature. * * @example * ```ts * const result = await cdp.endUser.sendSolanaAsset({ * userId: "user-123", * address: "So1ana...", * to: "Recipi...", * amount: "1000000", * network: "solana-devnet" * }); * console.log(result.transactionSignature); * ``` */ async sendSolanaAsset(options) { analytics_js_1.Analytics.trackAction({ action: "end_user_send_solana_asset" }); const asset = options.asset ?? "usdc"; return index_js_1.CdpOpenApiClient.sendSolanaAssetWithEndUserAccount(options.userId, options.address, asset, { to: options.to, amount: options.amount, network: options.network, createRecipientAta: options.createRecipientAta, }, undefined, options.idempotencyKey); } /** * Validates an end user's access token. Throws an error if the access token is invalid. * * @param options - The options for validating an access token. * * @returns The end user object if the access token is valid. */ async validateAccessToken(options) { analytics_js_1.Analytics.trackAction({ action: "validate_access_token", }); const { accessToken } = options; const endUser = await index_js_1.CdpOpenApiClient.validateEndUserAccessToken({ accessToken, }); return (0, toEndUserAccount_js_1.toEndUserAccount)(index_js_1.CdpOpenApiClient, { endUser }); } /** * Imports an existing private key for an end user. * * @param options - The options for importing an end user. * * @returns A promise that resolves to the imported end user. * * @example **Import an end user with an EVM private key** * ```ts * const endUser = await cdp.endUser.importEndUser({ * authenticationMethods: [ * { type: "sms", phoneNumber: "+12055555555" } * ], * privateKey: "0x...", * keyType: "evm" * }); * ``` * * @example **Import an end user with a Solana private key (base58)** * ```ts * const endUser = await cdp.endUser.importEndUser({ * authenticationMethods: [ * { type: "sms", phoneNumber: "+12055555555" } * ], * privateKey: "3Kzj...", * keyType: "solana" * }); * ``` */ async importEndUser(options) { analytics_js_1.Analytics.trackAction({ action: "import_end_user", }); const userId = options.userId ?? (0, crypto_1.randomUUID)(); let privateKeyBytes; if (options.keyType === "evm") { // EVM: expect hex string (with or without 0x prefix) if (typeof options.privateKey !== "string") { throw new errors_js_1.UserInputValidationError("EVM private key must be a hex string"); } const privateKeyHex = options.privateKey.startsWith("0x") ? options.privateKey.slice(2) : options.privateKey; if (!/^[0-9a-fA-F]+$/.test(privateKeyHex)) { throw new errors_js_1.UserInputValidationError("Private key must be a valid hexadecimal string"); } privateKeyBytes = Buffer.from(privateKeyHex, "hex"); } else { // Solana: expect base58 string or raw bytes (32 or 64 bytes) if (typeof options.privateKey === "string") { privateKeyBytes = bs58_1.default.decode(options.privateKey); } else { privateKeyBytes = options.privateKey; } if (privateKeyBytes.length !== 32 && privateKeyBytes.length !== 64) { throw new errors_js_1.UserInputValidationError("Invalid Solana private key length"); } // Truncate 64-byte keys to 32 bytes (seed only) if (privateKeyBytes.length === 64) { privateKeyBytes = privateKeyBytes.subarray(0, 32); } } const encryptedPrivateKey = (0, crypto_1.publicEncrypt)({ key: options.encryptionPublicKey ?? constants_js_1.ImportAccountPublicRSAKey, padding: crypto_1.constants.RSA_PKCS1_OAEP_PADDING, oaepHash: "sha256", }, privateKeyBytes); const endUser = await index_js_1.CdpOpenApiClient.importEndUser({ userId, authenticationMethods: options.authenticationMethods, encryptedPrivateKey: encryptedPrivateKey.toString("base64"), keyType: options.keyType, }, options.idempotencyKey); return (0, toEndUserAccount_js_1.toEndUserAccount)(index_js_1.CdpOpenApiClient, { endUser }); } } exports.EndUserClient = EndUserClient; //# sourceMappingURL=endUser.js.map