@coinbase/cdp-sdk 0.0.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +165 -0
- package/dist/accounts/evm/toEvmServerAccount.d.ts +19 -0
- package/dist/accounts/evm/toEvmServerAccount.js +42 -0
- package/dist/accounts/evm/toEvmSmartAccount.d.ts +24 -0
- package/dist/accounts/evm/toEvmSmartAccount.js +24 -0
- package/dist/accounts/types.d.ts +45 -0
- package/dist/accounts/types.js +2 -0
- package/dist/actions/evm/sendUserOperation.d.ts +95 -0
- package/dist/actions/evm/sendUserOperation.js +87 -0
- package/dist/actions/evm/waitForUserOperation.d.ts +63 -0
- package/dist/actions/evm/waitForUserOperation.js +60 -0
- package/dist/analytics.d.ts +30 -0
- package/dist/analytics.js +89 -0
- package/dist/auth/errors.d.ts +45 -0
- package/dist/auth/errors.js +62 -0
- package/dist/auth/hooks/axios/index.d.ts +1 -0
- package/dist/auth/hooks/axios/index.js +17 -0
- package/dist/auth/hooks/axios/withAuth.d.ts +37 -0
- package/dist/auth/hooks/axios/withAuth.js +73 -0
- package/dist/auth/index.d.ts +4 -0
- package/dist/auth/index.js +43 -0
- package/dist/auth/utils/http.d.ts +60 -0
- package/dist/auth/utils/http.js +72 -0
- package/dist/auth/utils/index.d.ts +2 -0
- package/dist/auth/utils/index.js +18 -0
- package/dist/auth/utils/jwt.d.ts +88 -0
- package/dist/auth/utils/jwt.js +235 -0
- package/dist/client/cdp.d.ts +43 -0
- package/dist/client/cdp.js +40 -0
- package/dist/client/evm/evm.d.ts +387 -0
- package/dist/client/evm/evm.js +520 -0
- package/dist/client/evm/evm.types.d.ts +254 -0
- package/dist/client/evm/evm.types.js +2 -0
- package/dist/client/evm/index.d.ts +1 -0
- package/dist/client/evm/index.js +5 -0
- package/dist/client/solana/index.d.ts +1 -0
- package/dist/client/solana/index.js +5 -0
- package/dist/client/solana/solana.d.ts +168 -0
- package/dist/client/solana/solana.js +207 -0
- package/dist/client/solana/solana.types.d.ts +94 -0
- package/dist/client/solana/solana.types.js +2 -0
- package/dist/constants.d.ts +4 -0
- package/dist/constants.js +7 -0
- package/dist/errors.d.ts +11 -0
- package/dist/errors.js +21 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +6 -0
- package/dist/openapi-client/cdpApiClient.d.ts +50 -0
- package/dist/openapi-client/cdpApiClient.js +146 -0
- package/dist/openapi-client/errors.d.ts +53 -0
- package/dist/openapi-client/errors.js +70 -0
- package/dist/openapi-client/generated/coinbaseDeveloperPlatformAPIs.schemas.d.ts +345 -0
- package/dist/openapi-client/generated/coinbaseDeveloperPlatformAPIs.schemas.js +54 -0
- package/dist/openapi-client/generated/evm-accounts/evm-accounts.d.ts +62 -0
- package/dist/openapi-client/generated/evm-accounts/evm-accounts.js +85 -0
- package/dist/openapi-client/generated/evm-accounts/evm-accounts.msw.d.ts +17 -0
- package/dist/openapi-client/generated/evm-accounts/evm-accounts.msw.js +113 -0
- package/dist/openapi-client/generated/evm-smart-accounts/evm-smart-accounts.d.ts +48 -0
- package/dist/openapi-client/generated/evm-smart-accounts/evm-smart-accounts.js +66 -0
- package/dist/openapi-client/generated/evm-smart-accounts/evm-smart-accounts.msw.d.ts +15 -0
- package/dist/openapi-client/generated/evm-smart-accounts/evm-smart-accounts.msw.js +99 -0
- package/dist/openapi-client/generated/faucets/faucets.d.ts +48 -0
- package/dist/openapi-client/generated/faucets/faucets.js +51 -0
- package/dist/openapi-client/generated/faucets/faucets.msw.d.ts +7 -0
- package/dist/openapi-client/generated/faucets/faucets.msw.js +43 -0
- package/dist/openapi-client/generated/index.msw.d.ts +4 -0
- package/dist/openapi-client/generated/index.msw.js +20 -0
- package/dist/openapi-client/generated/solana-accounts/solana-accounts.d.ts +61 -0
- package/dist/openapi-client/generated/solana-accounts/solana-accounts.js +79 -0
- package/dist/openapi-client/generated/solana-accounts/solana-accounts.msw.d.ts +15 -0
- package/dist/openapi-client/generated/solana-accounts/solana-accounts.msw.js +99 -0
- package/dist/openapi-client/index.d.ts +55 -0
- package/dist/openapi-client/index.js +65 -0
- package/dist/types/calls.d.ts +13 -0
- package/dist/types/calls.js +4 -0
- package/dist/types/contract.d.ts +30 -0
- package/dist/types/contract.js +4 -0
- package/dist/types/misc.d.ts +3 -0
- package/dist/types/misc.js +3 -0
- package/dist/types/multicall.d.ts +9 -0
- package/dist/types/multicall.js +2 -0
- package/dist/types/utils.d.ts +196 -0
- package/dist/types/utils.js +4 -0
- package/dist/utils/wait.d.ts +28 -0
- package/dist/utils/wait.js +34 -0
- package/package.json +72 -5
- package/index.js +0 -1
package/README.md
ADDED
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
# Coinbase Developer Platform (CDP) TypeScript SDK
|
|
2
|
+
|
|
3
|
+
## Table of Contents
|
|
4
|
+
|
|
5
|
+
- [CDP SDK](#cdp-sdk)
|
|
6
|
+
- [Installation](#installation)
|
|
7
|
+
- [API Keys](#api-keys)
|
|
8
|
+
- [Usage](#usage)
|
|
9
|
+
- [Authentication tools](#authentication-tools)
|
|
10
|
+
- [Error Reporting](#error-reporting)
|
|
11
|
+
- [License](#license)
|
|
12
|
+
- [Support](#support)
|
|
13
|
+
- [Security](#security)
|
|
14
|
+
|
|
15
|
+
> [!TIP]
|
|
16
|
+
> If you're looking to contribute to the SDK, please see the [Contributing Guide](https://github.com/coinbase/cdp-sdk/blob/main/typescript/CONTRIBUTING.md).
|
|
17
|
+
|
|
18
|
+
## CDP SDK
|
|
19
|
+
|
|
20
|
+
This module contains the TypeScript CDP SDK, which is a library that provides a client for interacting with the [Coinbase Developer Platform (CDP)](https://docs.cdp.coinbase.com/). It includes a CDP Client for interacting with EVM and Solana APIs to create accounts and send transactions, as well as authentication tools for interacting directly with the CDP APIs.
|
|
21
|
+
|
|
22
|
+
## Installation
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
npm install @coinbase/cdp-sdk
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## API Keys
|
|
29
|
+
|
|
30
|
+
To start, [create a CDP API Key](https://portal.cdp.coinbase.com/access/api). Save the `API Key ID` and `API Key Secret` for use in the SDK. You will also need to create a wallet secret in the [CDP Portal](https://portal.cdp.coinbase.com/products/wallet-api) to sign transactions.
|
|
31
|
+
|
|
32
|
+
## Usage
|
|
33
|
+
|
|
34
|
+
### Initialization
|
|
35
|
+
|
|
36
|
+
#### You can import the SDK as follows:
|
|
37
|
+
|
|
38
|
+
```typescript
|
|
39
|
+
import { CdpClient } from "@coinbase/cdp-sdk";
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
#### Then, initialize the client as follows:
|
|
43
|
+
|
|
44
|
+
```typescript
|
|
45
|
+
const cdp = new CdpClient({
|
|
46
|
+
apiKeyId: "YOUR_API_KEY_ID",
|
|
47
|
+
apiKeySecret: "YOUR_API_KEY_SECRET",
|
|
48
|
+
walletSecret: "YOUR_WALLET_SECRET",
|
|
49
|
+
});
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### Creating EVM or Solana accounts
|
|
53
|
+
|
|
54
|
+
#### Create an EVM account as follows:
|
|
55
|
+
|
|
56
|
+
```typescript
|
|
57
|
+
const evmAccount = await cdp.evm.createAccount();
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
#### Create a Solana account as follows:
|
|
61
|
+
|
|
62
|
+
```typescript
|
|
63
|
+
const solanaAccount = await cdp.solana.createAccount();
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### Testnet faucet
|
|
67
|
+
|
|
68
|
+
You can use the faucet function to request testnet ETH or SOL from the CDP.
|
|
69
|
+
|
|
70
|
+
#### Request testnet ETH as follows:
|
|
71
|
+
|
|
72
|
+
```typescript
|
|
73
|
+
const faucetResp = await cdp.evm.requestFaucet({
|
|
74
|
+
address: evmAccount.address,
|
|
75
|
+
network: "base-sepolia",
|
|
76
|
+
token: "eth",
|
|
77
|
+
});
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
#### Request testnet SOL as follows:
|
|
81
|
+
|
|
82
|
+
```typescript
|
|
83
|
+
const faucetResp = await cdp.solana.requestFaucet({
|
|
84
|
+
address: fromAddress,
|
|
85
|
+
token: "sol",
|
|
86
|
+
});
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### Sending transactions
|
|
90
|
+
|
|
91
|
+
For EVM, we recommend using viem to send transactions. See the [examples](https://github.com/coinbase/cdp-sdk/tree/main/typescript/src/examples/evm/sendTransaction.ts). For Solana, we recommend using the `@solana/web3.js` library to send transactions. See the [examples](https://github.com/coinbase/cdp-sdk/tree/main/typescript/src/examples/solana/signAndSendTransaction.ts).
|
|
92
|
+
|
|
93
|
+
### EVM Smart Accounts
|
|
94
|
+
|
|
95
|
+
For EVM, we support Smart Accounts which are account-abstraction (ERC-4337) accounts. Currently there is only support for Base Sepolia and Base Mainnet for Smart Accounts.
|
|
96
|
+
|
|
97
|
+
#### Create an EVM account and a smart account as follows:
|
|
98
|
+
|
|
99
|
+
```typescript
|
|
100
|
+
const evmAccount = await cdp.evm.createAccount();
|
|
101
|
+
const smartAccount = await cdp.evm.createSmartAccount({
|
|
102
|
+
owner: evmAccount,
|
|
103
|
+
});
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
#### Sending User Operations
|
|
107
|
+
|
|
108
|
+
```typescript
|
|
109
|
+
const userOperation = await cdp.evm.sendUserOperation({
|
|
110
|
+
smartAccount: smartAccount,
|
|
111
|
+
network: "base-sepolia",
|
|
112
|
+
calls: [
|
|
113
|
+
{
|
|
114
|
+
to: "0x0000000000000000000000000000000000000000",
|
|
115
|
+
value: parseEther("0.000001"),
|
|
116
|
+
data: "0x",
|
|
117
|
+
},
|
|
118
|
+
],
|
|
119
|
+
});
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
#### In Base Sepolia, all user operations are gasless by default. If you'd like to specify a different paymaster, you can do so as follows:
|
|
123
|
+
|
|
124
|
+
```typescript
|
|
125
|
+
const userOperation = await cdp.sendUserOperation({
|
|
126
|
+
smartAccount: smartAccount,
|
|
127
|
+
network: "base-sepolia",
|
|
128
|
+
calls: [
|
|
129
|
+
{
|
|
130
|
+
to: "0x0000000000000000000000000000000000000000",
|
|
131
|
+
value: parseEther("0"),
|
|
132
|
+
data: "0x",
|
|
133
|
+
},
|
|
134
|
+
],
|
|
135
|
+
paymasterUrl: "https://some-paymaster-url.com",
|
|
136
|
+
});
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
## Authentication tools
|
|
140
|
+
|
|
141
|
+
This SDK also contains simple tools for authenticating REST API requests to the [Coinbase Developer Platform (CDP)](https://docs.cdp.coinbase.com/). See the [Auth README](src/auth/README.md) for more details.
|
|
142
|
+
|
|
143
|
+
## Error Reporting
|
|
144
|
+
|
|
145
|
+
This SDK contains error reporting functionality that sends error events to the CDP. If you would like to disable this behavior, you can set the `DISABLE_CDP_ERROR_REPORTING` environment variable to `true`.
|
|
146
|
+
|
|
147
|
+
```bash
|
|
148
|
+
DISABLE_CDP_ERROR_REPORTING=true
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
## License
|
|
152
|
+
|
|
153
|
+
This project is licensed under the MIT License - see the [LICENSE](https://github.com/coinbase/cdp-sdk/tree/main/LICENSE.md) file for details.
|
|
154
|
+
|
|
155
|
+
## Support
|
|
156
|
+
|
|
157
|
+
For feature requests, feedback, or questions, please reach out to us in the **#cdp-sdk** channel of the [Coinbase Developer Platform Discord](https://discord.com/invite/cdp).
|
|
158
|
+
|
|
159
|
+
- [API Reference](https://docs.cdp.coinbase.com/api-v2/docs/welcome)
|
|
160
|
+
- [SDK Docs](https://coinbase.github.io/cdp-sdk/typescript)
|
|
161
|
+
- [GitHub Issues](https://github.com/coinbase/cdp-sdk/issues)
|
|
162
|
+
|
|
163
|
+
## Security
|
|
164
|
+
|
|
165
|
+
If you discover a security vulnerability within this SDK, please see our [Security Policy](https://github.com/coinbase/cdp-sdk/tree/main/SECURITY.md) for disclosure information.
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { EvmServerAccount } from "../types";
|
|
2
|
+
import { CdpOpenApiClientType, EvmAccount } from "../../openapi-client";
|
|
3
|
+
/**
|
|
4
|
+
* Options for converting a pre-existing EvmAccount to a EvmServerAccount.
|
|
5
|
+
*/
|
|
6
|
+
export type ToEvmServerAccountOptions = {
|
|
7
|
+
/** The EvmAccount that was previously created. */
|
|
8
|
+
account: EvmAccount;
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* Creates a Server-managed EvmAccount instance from an existing EvmAccount.
|
|
12
|
+
* Use this to interact with previously deployed EvmAccounts, rather than creating new ones.
|
|
13
|
+
*
|
|
14
|
+
* @param {CdpOpenApiClientType} apiClient - The API client.
|
|
15
|
+
* @param {ToEvmServerAccountOptions} options - Configuration options.
|
|
16
|
+
* @param {EvmAccount} options.account - The EvmAccount that was previously created.
|
|
17
|
+
* @returns {EvmServerAccount} A configured EvmAccount instance ready for signing.
|
|
18
|
+
*/
|
|
19
|
+
export declare function toEvmServerAccount(apiClient: CdpOpenApiClientType, options: ToEvmServerAccountOptions): EvmServerAccount;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.toEvmServerAccount = toEvmServerAccount;
|
|
4
|
+
const viem_1 = require("viem");
|
|
5
|
+
/**
|
|
6
|
+
* Creates a Server-managed EvmAccount instance from an existing EvmAccount.
|
|
7
|
+
* Use this to interact with previously deployed EvmAccounts, rather than creating new ones.
|
|
8
|
+
*
|
|
9
|
+
* @param {CdpOpenApiClientType} apiClient - The API client.
|
|
10
|
+
* @param {ToEvmServerAccountOptions} options - Configuration options.
|
|
11
|
+
* @param {EvmAccount} options.account - The EvmAccount that was previously created.
|
|
12
|
+
* @returns {EvmServerAccount} A configured EvmAccount instance ready for signing.
|
|
13
|
+
*/
|
|
14
|
+
function toEvmServerAccount(apiClient, options) {
|
|
15
|
+
const account = {
|
|
16
|
+
address: options.account.address,
|
|
17
|
+
async signMessage({ message }) {
|
|
18
|
+
const result = await apiClient.signEvmMessage(options.account.address, {
|
|
19
|
+
message: message.toString(),
|
|
20
|
+
});
|
|
21
|
+
return result.signature;
|
|
22
|
+
},
|
|
23
|
+
async sign(parameters) {
|
|
24
|
+
const result = await apiClient.signEvmHash(options.account.address, {
|
|
25
|
+
hash: parameters.hash,
|
|
26
|
+
});
|
|
27
|
+
return result.signature;
|
|
28
|
+
},
|
|
29
|
+
async signTransaction(transaction) {
|
|
30
|
+
const result = await apiClient.signEvmTransaction(options.account.address, {
|
|
31
|
+
transaction: (0, viem_1.serializeTransaction)(transaction),
|
|
32
|
+
});
|
|
33
|
+
return result.signedTransaction;
|
|
34
|
+
},
|
|
35
|
+
async signTypedData() {
|
|
36
|
+
throw new Error("Not implemented");
|
|
37
|
+
},
|
|
38
|
+
name: options.account.name,
|
|
39
|
+
type: "evm-server",
|
|
40
|
+
};
|
|
41
|
+
return account;
|
|
42
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { EvmAccount, EvmSmartAccount } from "../types";
|
|
2
|
+
import { EvmSmartAccount as EvmSmartAccountModel } from "../../openapi-client";
|
|
3
|
+
/**
|
|
4
|
+
* Options for converting a pre-existing EvmSmartAccount and owner to a EvmSmartAccount
|
|
5
|
+
*/
|
|
6
|
+
export type ToEvmSmartAccountOptions = {
|
|
7
|
+
/** The pre-existing EvmSmartAccount. */
|
|
8
|
+
smartAccount: EvmSmartAccountModel;
|
|
9
|
+
/** The owner of the smart account. */
|
|
10
|
+
owner: EvmAccount;
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Creates a EvmSmartAccount instance from an existing EvmSmartAccount and owner.
|
|
14
|
+
* Use this to interact with previously deployed EvmSmartAccounts, rather than creating new ones.
|
|
15
|
+
*
|
|
16
|
+
* The owner must be the original owner of the evm smart account.
|
|
17
|
+
*
|
|
18
|
+
* @param {ToEvmSmartAccountOptions} options - Configuration options.
|
|
19
|
+
* @param {EvmSmartAccount} options.smartAccount - The deployed evm smart account.
|
|
20
|
+
* @param {EvmAccount} options.owner - The owner which signs for the smart account.
|
|
21
|
+
* @returns {EvmSmartAccount} A configured EvmSmartAccount instance ready for user operation submission.
|
|
22
|
+
* @throws {Error} If the account is not an original owner of the smart account.
|
|
23
|
+
*/
|
|
24
|
+
export declare function toEvmSmartAccount(options: ToEvmSmartAccountOptions): EvmSmartAccount;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.toEvmSmartAccount = toEvmSmartAccount;
|
|
4
|
+
/**
|
|
5
|
+
* Creates a EvmSmartAccount instance from an existing EvmSmartAccount and owner.
|
|
6
|
+
* Use this to interact with previously deployed EvmSmartAccounts, rather than creating new ones.
|
|
7
|
+
*
|
|
8
|
+
* The owner must be the original owner of the evm smart account.
|
|
9
|
+
*
|
|
10
|
+
* @param {ToEvmSmartAccountOptions} options - Configuration options.
|
|
11
|
+
* @param {EvmSmartAccount} options.smartAccount - The deployed evm smart account.
|
|
12
|
+
* @param {EvmAccount} options.owner - The owner which signs for the smart account.
|
|
13
|
+
* @returns {EvmSmartAccount} A configured EvmSmartAccount instance ready for user operation submission.
|
|
14
|
+
* @throws {Error} If the account is not an original owner of the smart account.
|
|
15
|
+
*/
|
|
16
|
+
function toEvmSmartAccount(options) {
|
|
17
|
+
const account = {
|
|
18
|
+
address: options.smartAccount.address,
|
|
19
|
+
owners: [options.owner],
|
|
20
|
+
name: options.smartAccount.name,
|
|
21
|
+
type: "evm-smart",
|
|
22
|
+
};
|
|
23
|
+
return account;
|
|
24
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { SignableMessage, TransactionSerializable, TypedData, TypedDataDefinition } from "viem";
|
|
2
|
+
import type { Hash, Hex, Address } from "../types/misc";
|
|
3
|
+
import { Prettify } from "../types/utils";
|
|
4
|
+
/**
|
|
5
|
+
* Base type for any Ethereum account with signing capabilities.
|
|
6
|
+
* For example, this could be an EVM ServerAccount, or a viem LocalAccount.
|
|
7
|
+
*/
|
|
8
|
+
export type EvmAccount = {
|
|
9
|
+
/** The address of the signer. */
|
|
10
|
+
address: Address;
|
|
11
|
+
/** Signs a message hash and returns the signature as a hex string. */
|
|
12
|
+
sign: (parameters: {
|
|
13
|
+
hash: Hash;
|
|
14
|
+
}) => Promise<Hex>;
|
|
15
|
+
/** Signs a message and returns the signature as a hex string. */
|
|
16
|
+
signMessage: (parameters: {
|
|
17
|
+
message: SignableMessage;
|
|
18
|
+
}) => Promise<Hex>;
|
|
19
|
+
/** Signs a transaction and returns the signed transaction as a hex string. */
|
|
20
|
+
signTransaction: (transaction: TransactionSerializable) => Promise<Hex>;
|
|
21
|
+
/** Signs a typed data and returns the signature as a hex string. */
|
|
22
|
+
signTypedData: <const typedData extends TypedData | Record<string, unknown>, primaryType extends keyof typedData | "EIP712Domain" = keyof typedData>(parameters: TypedDataDefinition<typedData, primaryType>) => Promise<Hex>;
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* Server-managed ethereum account
|
|
26
|
+
*/
|
|
27
|
+
export type EvmServerAccount = Prettify<EvmAccount & {
|
|
28
|
+
/** Optional name for the server account. */
|
|
29
|
+
name?: string;
|
|
30
|
+
/** Indicates this is a server-managed account. */
|
|
31
|
+
type: "evm-server";
|
|
32
|
+
}>;
|
|
33
|
+
/**
|
|
34
|
+
* Ethereum smart account which supports account abstraction features like user operations, batch transactions, and paymaster.
|
|
35
|
+
*/
|
|
36
|
+
export type EvmSmartAccount = {
|
|
37
|
+
/** The smart account's address. */
|
|
38
|
+
address: Address;
|
|
39
|
+
/** The name of the smart account. */
|
|
40
|
+
name?: string;
|
|
41
|
+
/** Array of accounts that own and can sign for the smart account (currently only supports one owner but will be extended to support multiple owners in the future). */
|
|
42
|
+
owners: EvmAccount[];
|
|
43
|
+
/** Identifier for the smart account type. */
|
|
44
|
+
type: "evm-smart";
|
|
45
|
+
};
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import type { EvmSmartAccount } from "../../accounts/types";
|
|
2
|
+
import { EvmUserOperationNetwork, EvmUserOperationStatus } from "../../openapi-client";
|
|
3
|
+
import type { Address, Hex } from "../../types/misc";
|
|
4
|
+
import type { Calls } from "../../types/calls";
|
|
5
|
+
import { CdpOpenApiClientType } from "../../openapi-client";
|
|
6
|
+
/**
|
|
7
|
+
* Options for sending a user operation.
|
|
8
|
+
*
|
|
9
|
+
* @template T - Array type for the calls parameter.
|
|
10
|
+
*/
|
|
11
|
+
export type SendUserOperationOptions<T extends readonly unknown[]> = {
|
|
12
|
+
/**
|
|
13
|
+
* Array of contract calls to execute in the user operation.
|
|
14
|
+
* Each call can either be:
|
|
15
|
+
* - A direct call with `to`, `value`, and `data`.
|
|
16
|
+
* - A contract call with `to`, `abi`, `functionName`, and `args`.
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* ```ts
|
|
20
|
+
* const calls = [
|
|
21
|
+
* {
|
|
22
|
+
* to: "0x1234567890123456789012345678901234567890",
|
|
23
|
+
* value: parseEther("0.0000005"),
|
|
24
|
+
* data: "0x",
|
|
25
|
+
* },
|
|
26
|
+
* {
|
|
27
|
+
* to: "0x1234567890123456789012345678901234567890",
|
|
28
|
+
* abi: erc20Abi,
|
|
29
|
+
* functionName: "transfer",
|
|
30
|
+
* args: [to, amount],
|
|
31
|
+
* },
|
|
32
|
+
* ]
|
|
33
|
+
* ```
|
|
34
|
+
*/
|
|
35
|
+
calls: Calls<T>;
|
|
36
|
+
/** Chain ID of the network to execute on. */
|
|
37
|
+
network: EvmUserOperationNetwork;
|
|
38
|
+
/** Optional URL of the paymaster service to use for gas sponsorship. Must be ERC-7677 compliant. */
|
|
39
|
+
paymasterUrl?: string;
|
|
40
|
+
/** The idempotency key. */
|
|
41
|
+
idempotencyKey?: string;
|
|
42
|
+
};
|
|
43
|
+
/**
|
|
44
|
+
* Return type for the sendUserOperation function.
|
|
45
|
+
*/
|
|
46
|
+
export type SendUserOperationReturnType = {
|
|
47
|
+
/** The address of the smart wallet. */
|
|
48
|
+
smartAccountAddress: Address;
|
|
49
|
+
/** The status of the user operation. */
|
|
50
|
+
status: typeof EvmUserOperationStatus.broadcast;
|
|
51
|
+
/** The hash of the user operation. This is not the transaction hash which is only available after the operation is completed.*/
|
|
52
|
+
userOpHash: Hex;
|
|
53
|
+
};
|
|
54
|
+
/**
|
|
55
|
+
* Sends a user operation to the network.
|
|
56
|
+
*
|
|
57
|
+
* @example
|
|
58
|
+
* ```ts
|
|
59
|
+
* import { sendUserOperation } from "@coinbase/cdp-sdk";
|
|
60
|
+
* import { parseEther } from "viem";
|
|
61
|
+
* import { CdpClient } from "@coinbase/cdp-sdk";
|
|
62
|
+
*
|
|
63
|
+
* const client = new CdpClient({
|
|
64
|
+
* apiKeyId: "your-api-key-id",
|
|
65
|
+
* apiKeySecret: "your-api-key-secret",
|
|
66
|
+
* walletSecret: "your-wallet-secret",
|
|
67
|
+
* });
|
|
68
|
+
*
|
|
69
|
+
* const ethAccount = await client.createEvmServerAccount()
|
|
70
|
+
* const smartAccount = await client.createEvmSmartAccount({ owner: ethAccount })
|
|
71
|
+
*
|
|
72
|
+
* const result = await sendUserOperation(client, smartAccount, {
|
|
73
|
+
* calls: [
|
|
74
|
+
* {
|
|
75
|
+
* abi: erc20Abi,
|
|
76
|
+
* functionName: "transfer",
|
|
77
|
+
* args: [to, amount],
|
|
78
|
+
* },
|
|
79
|
+
* {
|
|
80
|
+
* to: "0x1234567890123456789012345678901234567890",
|
|
81
|
+
* data: "0x",
|
|
82
|
+
* value: parseEther("0.0000005"),
|
|
83
|
+
* },
|
|
84
|
+
* ],
|
|
85
|
+
* network: "base-sepolia",
|
|
86
|
+
* paymasterUrl: "https://api.developer.coinbase.com/rpc/v1/base/someapikey",
|
|
87
|
+
* });
|
|
88
|
+
* ```
|
|
89
|
+
*
|
|
90
|
+
* @param {CdpOpenApiClientType} client - The client to use to send the user operation.
|
|
91
|
+
* @param {EvmSmartAccount} smartAccount - The smart account to send the user operation from.
|
|
92
|
+
* @param {SendUserOperationOptions<T>} options - The options for the user operation.
|
|
93
|
+
* @returns {Promise<SendUserOperationReturnType>} The result of the user operation.
|
|
94
|
+
*/
|
|
95
|
+
export declare function sendUserOperation<T extends readonly unknown[]>(client: CdpOpenApiClientType, smartAccount: EvmSmartAccount, options: SendUserOperationOptions<T>): Promise<SendUserOperationReturnType>;
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.sendUserOperation = sendUserOperation;
|
|
4
|
+
const viem_1 = require("viem");
|
|
5
|
+
/**
|
|
6
|
+
* Sends a user operation to the network.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```ts
|
|
10
|
+
* import { sendUserOperation } from "@coinbase/cdp-sdk";
|
|
11
|
+
* import { parseEther } from "viem";
|
|
12
|
+
* import { CdpClient } from "@coinbase/cdp-sdk";
|
|
13
|
+
*
|
|
14
|
+
* const client = new CdpClient({
|
|
15
|
+
* apiKeyId: "your-api-key-id",
|
|
16
|
+
* apiKeySecret: "your-api-key-secret",
|
|
17
|
+
* walletSecret: "your-wallet-secret",
|
|
18
|
+
* });
|
|
19
|
+
*
|
|
20
|
+
* const ethAccount = await client.createEvmServerAccount()
|
|
21
|
+
* const smartAccount = await client.createEvmSmartAccount({ owner: ethAccount })
|
|
22
|
+
*
|
|
23
|
+
* const result = await sendUserOperation(client, smartAccount, {
|
|
24
|
+
* calls: [
|
|
25
|
+
* {
|
|
26
|
+
* abi: erc20Abi,
|
|
27
|
+
* functionName: "transfer",
|
|
28
|
+
* args: [to, amount],
|
|
29
|
+
* },
|
|
30
|
+
* {
|
|
31
|
+
* to: "0x1234567890123456789012345678901234567890",
|
|
32
|
+
* data: "0x",
|
|
33
|
+
* value: parseEther("0.0000005"),
|
|
34
|
+
* },
|
|
35
|
+
* ],
|
|
36
|
+
* network: "base-sepolia",
|
|
37
|
+
* paymasterUrl: "https://api.developer.coinbase.com/rpc/v1/base/someapikey",
|
|
38
|
+
* });
|
|
39
|
+
* ```
|
|
40
|
+
*
|
|
41
|
+
* @param {CdpOpenApiClientType} client - The client to use to send the user operation.
|
|
42
|
+
* @param {EvmSmartAccount} smartAccount - The smart account to send the user operation from.
|
|
43
|
+
* @param {SendUserOperationOptions<T>} options - The options for the user operation.
|
|
44
|
+
* @returns {Promise<SendUserOperationReturnType>} The result of the user operation.
|
|
45
|
+
*/
|
|
46
|
+
async function sendUserOperation(client, smartAccount, options) {
|
|
47
|
+
const { calls, network, paymasterUrl } = options;
|
|
48
|
+
if (calls.length === 0) {
|
|
49
|
+
throw new Error("Calls array is empty");
|
|
50
|
+
}
|
|
51
|
+
const encodedCalls = calls.map(call => {
|
|
52
|
+
const value = (call.value ?? BigInt(0)).toString();
|
|
53
|
+
if ("abi" in call && call.abi && "functionName" in call) {
|
|
54
|
+
return {
|
|
55
|
+
to: call.to,
|
|
56
|
+
data: (0, viem_1.encodeFunctionData)({
|
|
57
|
+
abi: call.abi,
|
|
58
|
+
functionName: call.functionName,
|
|
59
|
+
args: call.args,
|
|
60
|
+
}),
|
|
61
|
+
value,
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
return {
|
|
65
|
+
to: call.to,
|
|
66
|
+
data: call.data ?? "0x",
|
|
67
|
+
value,
|
|
68
|
+
};
|
|
69
|
+
});
|
|
70
|
+
const createOpResponse = await client.prepareUserOperation(smartAccount.address, {
|
|
71
|
+
network,
|
|
72
|
+
calls: encodedCalls,
|
|
73
|
+
paymasterUrl,
|
|
74
|
+
});
|
|
75
|
+
const owner = smartAccount.owners[0];
|
|
76
|
+
const signature = await owner.sign({
|
|
77
|
+
hash: createOpResponse.userOpHash,
|
|
78
|
+
});
|
|
79
|
+
const broadcastResponse = await client.sendUserOperation(smartAccount.address, createOpResponse.userOpHash, {
|
|
80
|
+
signature,
|
|
81
|
+
}, options.idempotencyKey);
|
|
82
|
+
return {
|
|
83
|
+
smartAccountAddress: smartAccount.address,
|
|
84
|
+
status: broadcastResponse.status,
|
|
85
|
+
userOpHash: createOpResponse.userOpHash,
|
|
86
|
+
};
|
|
87
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import type { Address, Hex } from "../../types/misc";
|
|
2
|
+
import { WaitOptions } from "../../utils/wait";
|
|
3
|
+
import { EvmUserOperationStatus, CdpOpenApiClientType } from "../../openapi-client";
|
|
4
|
+
/**
|
|
5
|
+
* Options for waiting for a user operation.
|
|
6
|
+
*/
|
|
7
|
+
export type WaitForUserOperationOptions = {
|
|
8
|
+
/** The hash of the user operation. */
|
|
9
|
+
userOpHash: Hex;
|
|
10
|
+
/** The address of the smart account. */
|
|
11
|
+
smartAccountAddress: Address;
|
|
12
|
+
/** Optional options for the wait operation. */
|
|
13
|
+
waitOptions?: WaitOptions;
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Represents a failed user operation.
|
|
17
|
+
*/
|
|
18
|
+
export type FailedOperation = {
|
|
19
|
+
/** The address of the smart account. */
|
|
20
|
+
smartAccountAddress: Address;
|
|
21
|
+
/** The status of the user operation. */
|
|
22
|
+
status: typeof EvmUserOperationStatus.failed;
|
|
23
|
+
/** The hash of the user operation. This is not the transaction hash which is only available after the operation is completed.*/
|
|
24
|
+
userOpHash: Hex;
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* Represents a completed user operation.
|
|
28
|
+
*/
|
|
29
|
+
export type CompletedOperation = {
|
|
30
|
+
/** The address of the smart account. */
|
|
31
|
+
smartAccountAddress: Address;
|
|
32
|
+
/** The transaction hash that executed the completed user operation. */
|
|
33
|
+
transactionHash: string;
|
|
34
|
+
/** The status of the user operation. */
|
|
35
|
+
status: typeof EvmUserOperationStatus.complete;
|
|
36
|
+
/** The hash of the user operation. This is not the transaction hash which is only available after the operation is completed.*/
|
|
37
|
+
userOpHash: Hex;
|
|
38
|
+
};
|
|
39
|
+
/**
|
|
40
|
+
* Represents the return type of the waitForUserOperation function.
|
|
41
|
+
*/
|
|
42
|
+
export type WaitForUserOperationReturnType = FailedOperation | CompletedOperation;
|
|
43
|
+
/**
|
|
44
|
+
* Waits for a user operation to complete or fail.
|
|
45
|
+
*
|
|
46
|
+
* @example
|
|
47
|
+
* ```ts
|
|
48
|
+
* import { waitForUserOperation } from "@coinbase/cdp-sdk";
|
|
49
|
+
*
|
|
50
|
+
* const result = await waitForUserOperation(client, {
|
|
51
|
+
* userOpHash: "0x1234567890123456789012345678901234567890",
|
|
52
|
+
* smartAccountAddress: "0x1234567890123456789012345678901234567890",
|
|
53
|
+
* waitOptions: {
|
|
54
|
+
* timeoutSeconds: 30,
|
|
55
|
+
* },
|
|
56
|
+
* });
|
|
57
|
+
* ```
|
|
58
|
+
*
|
|
59
|
+
* @param {CdpOpenApiClientType} client - The client to use to wait for the user operation.
|
|
60
|
+
* @param {WaitForUserOperationOptions} options - The options for the wait operation.
|
|
61
|
+
* @returns {Promise<WaitForUserOperationReturnType>} The result of the user operation.
|
|
62
|
+
*/
|
|
63
|
+
export declare function waitForUserOperation(client: CdpOpenApiClientType, options: WaitForUserOperationOptions): Promise<WaitForUserOperationReturnType>;
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.waitForUserOperation = waitForUserOperation;
|
|
4
|
+
const wait_1 = require("../../utils/wait");
|
|
5
|
+
const openapi_client_1 = require("../../openapi-client");
|
|
6
|
+
/**
|
|
7
|
+
* Waits for a user operation to complete or fail.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```ts
|
|
11
|
+
* import { waitForUserOperation } from "@coinbase/cdp-sdk";
|
|
12
|
+
*
|
|
13
|
+
* const result = await waitForUserOperation(client, {
|
|
14
|
+
* userOpHash: "0x1234567890123456789012345678901234567890",
|
|
15
|
+
* smartAccountAddress: "0x1234567890123456789012345678901234567890",
|
|
16
|
+
* waitOptions: {
|
|
17
|
+
* timeoutSeconds: 30,
|
|
18
|
+
* },
|
|
19
|
+
* });
|
|
20
|
+
* ```
|
|
21
|
+
*
|
|
22
|
+
* @param {CdpOpenApiClientType} client - The client to use to wait for the user operation.
|
|
23
|
+
* @param {WaitForUserOperationOptions} options - The options for the wait operation.
|
|
24
|
+
* @returns {Promise<WaitForUserOperationReturnType>} The result of the user operation.
|
|
25
|
+
*/
|
|
26
|
+
async function waitForUserOperation(client, options) {
|
|
27
|
+
const { userOpHash, smartAccountAddress } = options;
|
|
28
|
+
const reload = async () => {
|
|
29
|
+
const response = await client.getUserOperation(smartAccountAddress, userOpHash);
|
|
30
|
+
return response;
|
|
31
|
+
};
|
|
32
|
+
const transform = (operation) => {
|
|
33
|
+
if (operation.status === openapi_client_1.EvmUserOperationStatus.failed) {
|
|
34
|
+
return {
|
|
35
|
+
smartAccountAddress: smartAccountAddress,
|
|
36
|
+
status: openapi_client_1.EvmUserOperationStatus.failed,
|
|
37
|
+
userOpHash: operation.userOpHash,
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
else if (operation.status === openapi_client_1.EvmUserOperationStatus.complete) {
|
|
41
|
+
return {
|
|
42
|
+
smartAccountAddress: smartAccountAddress,
|
|
43
|
+
transactionHash: operation.transactionHash,
|
|
44
|
+
status: openapi_client_1.EvmUserOperationStatus.complete,
|
|
45
|
+
userOpHash: operation.userOpHash,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
throw new Error("User operation is not terminal");
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
const waitOptions = options.waitOptions || {
|
|
53
|
+
timeoutSeconds: 30,
|
|
54
|
+
};
|
|
55
|
+
return await (0, wait_1.wait)(reload, isTerminal, transform, waitOptions);
|
|
56
|
+
}
|
|
57
|
+
const isTerminal = (operation) => {
|
|
58
|
+
return (operation.status === openapi_client_1.EvmUserOperationStatus.complete ||
|
|
59
|
+
operation.status === openapi_client_1.EvmUserOperationStatus.failed);
|
|
60
|
+
};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The data in an error event
|
|
3
|
+
*/
|
|
4
|
+
type ErrorEventData = {
|
|
5
|
+
/**
|
|
6
|
+
* The API method where the error occurred, e.g. createAccount, getAccount
|
|
7
|
+
*/
|
|
8
|
+
method: string;
|
|
9
|
+
/**
|
|
10
|
+
* The error message
|
|
11
|
+
*/
|
|
12
|
+
message: string;
|
|
13
|
+
/**
|
|
14
|
+
* The error stack trace
|
|
15
|
+
*/
|
|
16
|
+
stack?: string;
|
|
17
|
+
/**
|
|
18
|
+
* The name of the event. This should match the name in AEC
|
|
19
|
+
*/
|
|
20
|
+
name: "error";
|
|
21
|
+
};
|
|
22
|
+
type EventData = ErrorEventData;
|
|
23
|
+
/**
|
|
24
|
+
* Sends an analytics event to the default endpoint
|
|
25
|
+
*
|
|
26
|
+
* @param event - The event data containing event-specific fields
|
|
27
|
+
* @returns Promise that resolves when the event is sent
|
|
28
|
+
*/
|
|
29
|
+
export declare function sendEvent(event: EventData): Promise<void>;
|
|
30
|
+
export {};
|