@chipi-stack/backend 0.1.0
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/dist/client-3HAMR0rB.d.mts +24 -0
- package/dist/client-3HAMR0rB.d.ts +24 -0
- package/dist/index.d.mts +52 -0
- package/dist/index.d.ts +52 -0
- package/dist/index.js +722 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +710 -0
- package/dist/index.mjs.map +1 -0
- package/dist/skus.d.mts +52 -0
- package/dist/skus.d.ts +52 -0
- package/dist/skus.js +87 -0
- package/dist/skus.js.map +1 -0
- package/dist/skus.mjs +85 -0
- package/dist/skus.mjs.map +1 -0
- package/dist/transactions.d.mts +50 -0
- package/dist/transactions.d.ts +50 -0
- package/dist/transactions.js +174 -0
- package/dist/transactions.js.map +1 -0
- package/dist/transactions.mjs +168 -0
- package/dist/transactions.mjs.map +1 -0
- package/dist/wallets.d.mts +38 -0
- package/dist/wallets.d.ts +38 -0
- package/dist/wallets.js +190 -0
- package/dist/wallets.js.map +1 -0
- package/dist/wallets.mjs +184 -0
- package/dist/wallets.mjs.map +1 -0
- package/package.json +99 -0
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var shared = require('@chipi-stack/shared');
|
|
4
|
+
var starknet = require('starknet');
|
|
5
|
+
var CryptoJS = require('crypto-js');
|
|
6
|
+
|
|
7
|
+
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
8
|
+
|
|
9
|
+
var CryptoJS__default = /*#__PURE__*/_interopDefault(CryptoJS);
|
|
10
|
+
|
|
11
|
+
// src/transactions.ts
|
|
12
|
+
var decryptPrivateKey = (encryptedPrivateKey, password) => {
|
|
13
|
+
if (!encryptedPrivateKey || !password) {
|
|
14
|
+
console.error("Encrypted private key and password are required");
|
|
15
|
+
return null;
|
|
16
|
+
}
|
|
17
|
+
try {
|
|
18
|
+
const bytes = CryptoJS__default.default.AES.decrypt(encryptedPrivateKey, password);
|
|
19
|
+
const decrypted = bytes.toString(CryptoJS__default.default.enc.Utf8);
|
|
20
|
+
if (!decrypted) {
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
return decrypted;
|
|
24
|
+
} catch (error) {
|
|
25
|
+
console.error("Decryption failed:", error);
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
// src/gasless.ts
|
|
31
|
+
var executePaymasterTransaction = async (params) => {
|
|
32
|
+
try {
|
|
33
|
+
const { encryptKey, wallet, calls, apiPublicKey, bearerToken, backendUrl } = params;
|
|
34
|
+
const privateKeyDecrypted = decryptPrivateKey(
|
|
35
|
+
wallet.encryptedPrivateKey,
|
|
36
|
+
encryptKey
|
|
37
|
+
);
|
|
38
|
+
if (!privateKeyDecrypted) {
|
|
39
|
+
throw new Error("Failed to decrypt private key");
|
|
40
|
+
}
|
|
41
|
+
const provider = new starknet.RpcProvider({
|
|
42
|
+
nodeUrl: "https://cloud.argent-api.com/v1/starknet/mainnet/rpc/v0.7"
|
|
43
|
+
});
|
|
44
|
+
const account = new starknet.Account(
|
|
45
|
+
provider,
|
|
46
|
+
wallet.publicKey,
|
|
47
|
+
privateKeyDecrypted
|
|
48
|
+
);
|
|
49
|
+
const typeDataResponse = await fetch(`${backendUrl}/transactions/prepare-typed-data`, {
|
|
50
|
+
method: "POST",
|
|
51
|
+
headers: {
|
|
52
|
+
"Content-Type": "application/json",
|
|
53
|
+
"Authorization": `Bearer ${bearerToken}`,
|
|
54
|
+
"X-API-Key": apiPublicKey
|
|
55
|
+
},
|
|
56
|
+
body: JSON.stringify({
|
|
57
|
+
publicKey: wallet.publicKey,
|
|
58
|
+
calls,
|
|
59
|
+
accountClassHash: "0x036078334509b514626504edc9fb252328d1a240e4e948bef8d0c08dff45927f"
|
|
60
|
+
})
|
|
61
|
+
});
|
|
62
|
+
if (!typeDataResponse.ok) {
|
|
63
|
+
const errorText = await typeDataResponse.text();
|
|
64
|
+
throw new Error(`Error en la API: ${errorText}`);
|
|
65
|
+
}
|
|
66
|
+
const typeData = await typeDataResponse.json();
|
|
67
|
+
const userSignature = await account.signMessage(typeData);
|
|
68
|
+
const executeTransaction = await fetch(`${backendUrl}/transactions/execute-sponsored-transaction`, {
|
|
69
|
+
method: "POST",
|
|
70
|
+
headers: {
|
|
71
|
+
"Content-Type": "application/json",
|
|
72
|
+
"Authorization": `Bearer ${bearerToken}`,
|
|
73
|
+
"X-API-Key": apiPublicKey
|
|
74
|
+
},
|
|
75
|
+
body: JSON.stringify({
|
|
76
|
+
publicKey: wallet.publicKey,
|
|
77
|
+
typeData,
|
|
78
|
+
userSignature: {
|
|
79
|
+
r: userSignature.r.toString(),
|
|
80
|
+
s: userSignature.s.toString(),
|
|
81
|
+
recovery: userSignature.recovery
|
|
82
|
+
}
|
|
83
|
+
})
|
|
84
|
+
});
|
|
85
|
+
if (!executeTransaction.ok) {
|
|
86
|
+
const errorText = await executeTransaction.text();
|
|
87
|
+
throw new Error(`Error en la API de ejecuci\xF3n: ${errorText}`);
|
|
88
|
+
}
|
|
89
|
+
const result = await executeTransaction.json();
|
|
90
|
+
if (!result.transactionHash) {
|
|
91
|
+
throw new Error("La respuesta no contiene el hash de la transacci\xF3n");
|
|
92
|
+
}
|
|
93
|
+
return result.transactionHash;
|
|
94
|
+
} catch (error) {
|
|
95
|
+
console.error("Error sending transaction with paymaster", error);
|
|
96
|
+
throw error;
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
// src/transactions.ts
|
|
101
|
+
var ChipiTransactions = class {
|
|
102
|
+
constructor(client) {
|
|
103
|
+
this.client = client;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Execute a gasless transaction using paymaster
|
|
107
|
+
*/
|
|
108
|
+
async executeTransaction(params) {
|
|
109
|
+
return executePaymasterTransaction({
|
|
110
|
+
...params,
|
|
111
|
+
apiPublicKey: this.client.getApiPublicKey(),
|
|
112
|
+
backendUrl: this.client.baseUrl
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Transfer tokens
|
|
117
|
+
*/
|
|
118
|
+
async transfer(params) {
|
|
119
|
+
const formattedAmount = shared.formatAmount(params.amount, params.decimals);
|
|
120
|
+
return this.executeTransaction({
|
|
121
|
+
encryptKey: params.encryptKey,
|
|
122
|
+
wallet: params.wallet,
|
|
123
|
+
bearerToken: params.bearerToken,
|
|
124
|
+
calls: [
|
|
125
|
+
{
|
|
126
|
+
contractAddress: params.contractAddress,
|
|
127
|
+
entrypoint: "transfer",
|
|
128
|
+
calldata: [
|
|
129
|
+
params.recipient,
|
|
130
|
+
formattedAmount,
|
|
131
|
+
"0x0"
|
|
132
|
+
]
|
|
133
|
+
}
|
|
134
|
+
]
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Approve token spending
|
|
139
|
+
*/
|
|
140
|
+
async approve(params) {
|
|
141
|
+
const formattedAmount = shared.formatAmount(params.amount, params.decimals);
|
|
142
|
+
return this.executeTransaction({
|
|
143
|
+
encryptKey: params.encryptKey,
|
|
144
|
+
wallet: params.wallet,
|
|
145
|
+
bearerToken: params.bearerToken,
|
|
146
|
+
calls: [
|
|
147
|
+
{
|
|
148
|
+
contractAddress: params.contractAddress,
|
|
149
|
+
entrypoint: "approve",
|
|
150
|
+
calldata: [
|
|
151
|
+
params.spender,
|
|
152
|
+
formattedAmount,
|
|
153
|
+
"0x0"
|
|
154
|
+
]
|
|
155
|
+
}
|
|
156
|
+
]
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Call any contract method
|
|
161
|
+
*/
|
|
162
|
+
async callAnyContract(params) {
|
|
163
|
+
return this.executeTransaction({
|
|
164
|
+
encryptKey: params.encryptKey,
|
|
165
|
+
wallet: params.wallet,
|
|
166
|
+
bearerToken: params.bearerToken,
|
|
167
|
+
calls: params.calls
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
};
|
|
171
|
+
|
|
172
|
+
exports.ChipiTransactions = ChipiTransactions;
|
|
173
|
+
//# sourceMappingURL=transactions.js.map
|
|
174
|
+
//# sourceMappingURL=transactions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/lib/encryption.ts","../src/gasless.ts","../src/transactions.ts"],"names":["CryptoJS","RpcProvider","Account","formatAmount"],"mappings":"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","file":"transactions.js","sourcesContent":["import CryptoJS from \"crypto-js\";\n\nexport const encryptPrivateKey = (\n privateKey: string,\n password: string,\n): string => {\n if (!privateKey || !password) {\n throw new Error(\"Private key and password are required\");\n }\n\n return CryptoJS.AES.encrypt(privateKey, password).toString();\n};\n\nexport const decryptPrivateKey = (\n encryptedPrivateKey: string,\n password: string,\n): string | null => {\n if (!encryptedPrivateKey || !password) {\n console.error(\"Encrypted private key and password are required\");\n return null;\n }\n\n try {\n const bytes = CryptoJS.AES.decrypt(encryptedPrivateKey, password);\n const decrypted = bytes.toString(CryptoJS.enc.Utf8);\n\n // Check if the decrypted string is empty\n if (!decrypted) {\n return null;\n }\n\n return decrypted;\n } catch (error) {\n console.error(\"Decryption failed:\", error);\n return null;\n }\n};\n","import type { ExecuteSponsoredTransactionResponse, ExecuteTransactionParams } from '@chipi-stack/types';\nimport { Account, RpcProvider, TypedData } from 'starknet';\nimport { decryptPrivateKey } from './lib';\n\n// This will need to be imported from the actual gasless SDK or implemented\n// For now, this is a placeholder implementation based on the original SDK\n\n/**\n * Execute a paymaster transaction (gasless)\n */\nexport const executePaymasterTransaction = async (\n params: ExecuteTransactionParams & {backendUrl: string} // Backend url shit is temporary\n): Promise<string> => {\n try {\n const { encryptKey, wallet, calls, apiPublicKey, bearerToken,backendUrl } = params;\n\n // Fetch the encrypted private key from clerk public metadata\n const privateKeyDecrypted = decryptPrivateKey(\n wallet.encryptedPrivateKey,\n encryptKey\n );\n\n if (!privateKeyDecrypted) {\n throw new Error(\"Failed to decrypt private key\");\n }\n\n const provider = new RpcProvider({\n nodeUrl: \"https://cloud.argent-api.com/v1/starknet/mainnet/rpc/v0.7\",\n });\n\n const account = new Account(\n provider,\n wallet.publicKey,\n privateKeyDecrypted\n );\n\n // Build the type data\n const typeDataResponse = await fetch(`${backendUrl}/transactions/prepare-typed-data`, {\n method: \"POST\",\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${bearerToken}`,\n 'X-API-Key': apiPublicKey,\n },\n body: JSON.stringify({\n publicKey: wallet.publicKey,\n calls: calls,\n accountClassHash: \"0x036078334509b514626504edc9fb252328d1a240e4e948bef8d0c08dff45927f\"\n }),\n });\n\n if (!typeDataResponse.ok) {\n const errorText = await typeDataResponse.text();\n throw new Error(`Error en la API: ${errorText}`);\n }\n\n const typeData = await typeDataResponse.json() as TypedData;\n\n // Sign the message\n const userSignature = await account.signMessage(typeData);\n\n \n // Execute the transaction\n const executeTransaction = await fetch(`${backendUrl}/transactions/execute-sponsored-transaction`, {\n method: \"POST\",\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${bearerToken}`,\n 'X-API-Key': apiPublicKey,\n },\n body: JSON.stringify({\n publicKey: wallet.publicKey,\n typeData: typeData,\n userSignature: {\n r: (userSignature as any).r.toString(),\n s: (userSignature as any).s.toString(),\n recovery: (userSignature as any).recovery\n }\n }),\n });\n\n if (!executeTransaction.ok) {\n const errorText = await executeTransaction.text();\n throw new Error(`Error en la API de ejecución: ${errorText}`);\n }\n\n const result = await executeTransaction.json() as ExecuteSponsoredTransactionResponse;\n \n if (!result.transactionHash) {\n throw new Error('La respuesta no contiene el hash de la transacción');\n }\n\n return result.transactionHash;\n } catch (error) {\n console.error(\"Error sending transaction with paymaster\", error);\n throw error;\n }\n};\n\n","import type {\n ExecuteTransactionParams,\n} from '@chipi-stack/types';\nimport { formatAmount } from '@chipi-stack/shared';\nimport { ChipiClient } from './client';\nimport { executePaymasterTransaction } from './gasless';\n\n/**\n * Transaction management utilities\n */\nexport class ChipiTransactions {\n constructor(private client: ChipiClient) {}\n /**\n * Execute a gasless transaction using paymaster\n */\n async executeTransaction(\n params: Omit<ExecuteTransactionParams, 'apiPublicKey'>\n ): Promise<string> {\n return executePaymasterTransaction({\n ...params,\n apiPublicKey: this.client.getApiPublicKey(),\n backendUrl: this.client.baseUrl,\n });\n }\n\n /**\n * Transfer tokens\n */\n async transfer(params: {\n encryptKey: string;\n wallet: any;\n contractAddress: string;\n recipient: string;\n amount: string | number;\n decimals?: number;\n bearerToken: string;\n }): Promise<string> {\n const formattedAmount = formatAmount(params.amount, params.decimals);\n return this.executeTransaction({\n encryptKey: params.encryptKey,\n wallet: params.wallet,\n bearerToken: params.bearerToken,\n calls: [\n {\n contractAddress: params.contractAddress,\n entrypoint: 'transfer',\n calldata: [\n params.recipient,\n formattedAmount,\n '0x0',\n ],\n },\n ],\n });\n }\n\n /**\n * Approve token spending\n */\n async approve(params: {\n encryptKey: string;\n wallet: any;\n contractAddress: string;\n spender: string;\n amount: string | number;\n decimals?: number;\n bearerToken: string;\n }): Promise<string> {\n const formattedAmount = formatAmount(params.amount, params.decimals);\n \n return this.executeTransaction({\n encryptKey: params.encryptKey,\n wallet: params.wallet,\n bearerToken: params.bearerToken,\n calls: [\n {\n contractAddress: params.contractAddress,\n entrypoint: 'approve',\n calldata: [\n params.spender,\n formattedAmount,\n '0x0',\n ],\n },\n ],\n });\n }\n\n /**\n * Call any contract method\n */\n async callAnyContract(params: {\n encryptKey: string;\n wallet: any;\n calls: any[];\n bearerToken: string;\n }): Promise<string> {\n return this.executeTransaction({\n encryptKey: params.encryptKey,\n wallet: params.wallet,\n bearerToken: params.bearerToken,\n calls: params.calls,\n });\n }\n}\n"]}
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import { formatAmount } from '@chipi-stack/shared';
|
|
2
|
+
import { RpcProvider, Account } from 'starknet';
|
|
3
|
+
import CryptoJS from 'crypto-js';
|
|
4
|
+
|
|
5
|
+
// src/transactions.ts
|
|
6
|
+
var decryptPrivateKey = (encryptedPrivateKey, password) => {
|
|
7
|
+
if (!encryptedPrivateKey || !password) {
|
|
8
|
+
console.error("Encrypted private key and password are required");
|
|
9
|
+
return null;
|
|
10
|
+
}
|
|
11
|
+
try {
|
|
12
|
+
const bytes = CryptoJS.AES.decrypt(encryptedPrivateKey, password);
|
|
13
|
+
const decrypted = bytes.toString(CryptoJS.enc.Utf8);
|
|
14
|
+
if (!decrypted) {
|
|
15
|
+
return null;
|
|
16
|
+
}
|
|
17
|
+
return decrypted;
|
|
18
|
+
} catch (error) {
|
|
19
|
+
console.error("Decryption failed:", error);
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
// src/gasless.ts
|
|
25
|
+
var executePaymasterTransaction = async (params) => {
|
|
26
|
+
try {
|
|
27
|
+
const { encryptKey, wallet, calls, apiPublicKey, bearerToken, backendUrl } = params;
|
|
28
|
+
const privateKeyDecrypted = decryptPrivateKey(
|
|
29
|
+
wallet.encryptedPrivateKey,
|
|
30
|
+
encryptKey
|
|
31
|
+
);
|
|
32
|
+
if (!privateKeyDecrypted) {
|
|
33
|
+
throw new Error("Failed to decrypt private key");
|
|
34
|
+
}
|
|
35
|
+
const provider = new RpcProvider({
|
|
36
|
+
nodeUrl: "https://cloud.argent-api.com/v1/starknet/mainnet/rpc/v0.7"
|
|
37
|
+
});
|
|
38
|
+
const account = new Account(
|
|
39
|
+
provider,
|
|
40
|
+
wallet.publicKey,
|
|
41
|
+
privateKeyDecrypted
|
|
42
|
+
);
|
|
43
|
+
const typeDataResponse = await fetch(`${backendUrl}/transactions/prepare-typed-data`, {
|
|
44
|
+
method: "POST",
|
|
45
|
+
headers: {
|
|
46
|
+
"Content-Type": "application/json",
|
|
47
|
+
"Authorization": `Bearer ${bearerToken}`,
|
|
48
|
+
"X-API-Key": apiPublicKey
|
|
49
|
+
},
|
|
50
|
+
body: JSON.stringify({
|
|
51
|
+
publicKey: wallet.publicKey,
|
|
52
|
+
calls,
|
|
53
|
+
accountClassHash: "0x036078334509b514626504edc9fb252328d1a240e4e948bef8d0c08dff45927f"
|
|
54
|
+
})
|
|
55
|
+
});
|
|
56
|
+
if (!typeDataResponse.ok) {
|
|
57
|
+
const errorText = await typeDataResponse.text();
|
|
58
|
+
throw new Error(`Error en la API: ${errorText}`);
|
|
59
|
+
}
|
|
60
|
+
const typeData = await typeDataResponse.json();
|
|
61
|
+
const userSignature = await account.signMessage(typeData);
|
|
62
|
+
const executeTransaction = await fetch(`${backendUrl}/transactions/execute-sponsored-transaction`, {
|
|
63
|
+
method: "POST",
|
|
64
|
+
headers: {
|
|
65
|
+
"Content-Type": "application/json",
|
|
66
|
+
"Authorization": `Bearer ${bearerToken}`,
|
|
67
|
+
"X-API-Key": apiPublicKey
|
|
68
|
+
},
|
|
69
|
+
body: JSON.stringify({
|
|
70
|
+
publicKey: wallet.publicKey,
|
|
71
|
+
typeData,
|
|
72
|
+
userSignature: {
|
|
73
|
+
r: userSignature.r.toString(),
|
|
74
|
+
s: userSignature.s.toString(),
|
|
75
|
+
recovery: userSignature.recovery
|
|
76
|
+
}
|
|
77
|
+
})
|
|
78
|
+
});
|
|
79
|
+
if (!executeTransaction.ok) {
|
|
80
|
+
const errorText = await executeTransaction.text();
|
|
81
|
+
throw new Error(`Error en la API de ejecuci\xF3n: ${errorText}`);
|
|
82
|
+
}
|
|
83
|
+
const result = await executeTransaction.json();
|
|
84
|
+
if (!result.transactionHash) {
|
|
85
|
+
throw new Error("La respuesta no contiene el hash de la transacci\xF3n");
|
|
86
|
+
}
|
|
87
|
+
return result.transactionHash;
|
|
88
|
+
} catch (error) {
|
|
89
|
+
console.error("Error sending transaction with paymaster", error);
|
|
90
|
+
throw error;
|
|
91
|
+
}
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
// src/transactions.ts
|
|
95
|
+
var ChipiTransactions = class {
|
|
96
|
+
constructor(client) {
|
|
97
|
+
this.client = client;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Execute a gasless transaction using paymaster
|
|
101
|
+
*/
|
|
102
|
+
async executeTransaction(params) {
|
|
103
|
+
return executePaymasterTransaction({
|
|
104
|
+
...params,
|
|
105
|
+
apiPublicKey: this.client.getApiPublicKey(),
|
|
106
|
+
backendUrl: this.client.baseUrl
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Transfer tokens
|
|
111
|
+
*/
|
|
112
|
+
async transfer(params) {
|
|
113
|
+
const formattedAmount = formatAmount(params.amount, params.decimals);
|
|
114
|
+
return this.executeTransaction({
|
|
115
|
+
encryptKey: params.encryptKey,
|
|
116
|
+
wallet: params.wallet,
|
|
117
|
+
bearerToken: params.bearerToken,
|
|
118
|
+
calls: [
|
|
119
|
+
{
|
|
120
|
+
contractAddress: params.contractAddress,
|
|
121
|
+
entrypoint: "transfer",
|
|
122
|
+
calldata: [
|
|
123
|
+
params.recipient,
|
|
124
|
+
formattedAmount,
|
|
125
|
+
"0x0"
|
|
126
|
+
]
|
|
127
|
+
}
|
|
128
|
+
]
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Approve token spending
|
|
133
|
+
*/
|
|
134
|
+
async approve(params) {
|
|
135
|
+
const formattedAmount = formatAmount(params.amount, params.decimals);
|
|
136
|
+
return this.executeTransaction({
|
|
137
|
+
encryptKey: params.encryptKey,
|
|
138
|
+
wallet: params.wallet,
|
|
139
|
+
bearerToken: params.bearerToken,
|
|
140
|
+
calls: [
|
|
141
|
+
{
|
|
142
|
+
contractAddress: params.contractAddress,
|
|
143
|
+
entrypoint: "approve",
|
|
144
|
+
calldata: [
|
|
145
|
+
params.spender,
|
|
146
|
+
formattedAmount,
|
|
147
|
+
"0x0"
|
|
148
|
+
]
|
|
149
|
+
}
|
|
150
|
+
]
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Call any contract method
|
|
155
|
+
*/
|
|
156
|
+
async callAnyContract(params) {
|
|
157
|
+
return this.executeTransaction({
|
|
158
|
+
encryptKey: params.encryptKey,
|
|
159
|
+
wallet: params.wallet,
|
|
160
|
+
bearerToken: params.bearerToken,
|
|
161
|
+
calls: params.calls
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
};
|
|
165
|
+
|
|
166
|
+
export { ChipiTransactions };
|
|
167
|
+
//# sourceMappingURL=transactions.mjs.map
|
|
168
|
+
//# sourceMappingURL=transactions.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/lib/encryption.ts","../src/gasless.ts","../src/transactions.ts"],"names":[],"mappings":";;;;;AAaO,IAAM,iBAAA,GAAoB,CAC/B,mBAAA,EACA,QAAA,KACkB;AAClB,EAAA,IAAI,CAAC,mBAAA,IAAuB,CAAC,QAAA,EAAU;AACrC,IAAA,OAAA,CAAQ,MAAM,iDAAiD,CAAA;AAC/D,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,IAAI;AACF,IAAA,MAAM,KAAA,GAAQ,QAAA,CAAS,GAAA,CAAI,OAAA,CAAQ,qBAAqB,QAAQ,CAAA;AAChE,IAAA,MAAM,SAAA,GAAY,KAAA,CAAM,QAAA,CAAS,QAAA,CAAS,IAAI,IAAI,CAAA;AAGlD,IAAA,IAAI,CAAC,SAAA,EAAW;AACd,MAAA,OAAO,IAAA;AAAA,IACT;AAEA,IAAA,OAAO,SAAA;AAAA,EACT,SAAS,KAAA,EAAO;AACd,IAAA,OAAA,CAAQ,KAAA,CAAM,sBAAsB,KAAK,CAAA;AACzC,IAAA,OAAO,IAAA;AAAA,EACT;AACF,CAAA;;;AC1BO,IAAM,2BAAA,GAA8B,OACzC,MAAA,KACoB;AACpB,EAAA,IAAI;AACF,IAAA,MAAM,EAAE,UAAA,EAAY,MAAA,EAAQ,OAAO,YAAA,EAAc,WAAA,EAAY,YAAW,GAAI,MAAA;AAG5E,IAAA,MAAM,mBAAA,GAAsB,iBAAA;AAAA,MAC1B,MAAA,CAAO,mBAAA;AAAA,MACP;AAAA,KACF;AAEA,IAAA,IAAI,CAAC,mBAAA,EAAqB;AACxB,MAAA,MAAM,IAAI,MAAM,+BAA+B,CAAA;AAAA,IACjD;AAEA,IAAA,MAAM,QAAA,GAAW,IAAI,WAAA,CAAY;AAAA,MAC/B,OAAA,EAAS;AAAA,KACV,CAAA;AAED,IAAA,MAAM,UAAU,IAAI,OAAA;AAAA,MAClB,QAAA;AAAA,MACA,MAAA,CAAO,SAAA;AAAA,MACP;AAAA,KACF;AAGA,IAAA,MAAM,gBAAA,GAAmB,MAAM,KAAA,CAAM,CAAA,EAAG,UAAU,CAAA,gCAAA,CAAA,EAAoC;AAAA,MACpF,MAAA,EAAQ,MAAA;AAAA,MACR,OAAA,EAAS;AAAA,QACP,cAAA,EAAgB,kBAAA;AAAA,QAChB,eAAA,EAAiB,UAAU,WAAW,CAAA,CAAA;AAAA,QACtC,WAAA,EAAa;AAAA,OACf;AAAA,MACA,IAAA,EAAM,KAAK,SAAA,CAAU;AAAA,QACnB,WAAW,MAAA,CAAO,SAAA;AAAA,QAClB,KAAA;AAAA,QACA,gBAAA,EAAkB;AAAA,OACnB;AAAA,KACF,CAAA;AAED,IAAA,IAAI,CAAC,iBAAiB,EAAA,EAAI;AACxB,MAAA,MAAM,SAAA,GAAY,MAAM,gBAAA,CAAiB,IAAA,EAAK;AAC9C,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,iBAAA,EAAoB,SAAS,CAAA,CAAE,CAAA;AAAA,IACjD;AAEA,IAAA,MAAM,QAAA,GAAW,MAAM,gBAAA,CAAiB,IAAA,EAAK;AAG7C,IAAA,MAAM,aAAA,GAAgB,MAAM,OAAA,CAAQ,WAAA,CAAY,QAAQ,CAAA;AAIxD,IAAA,MAAM,kBAAA,GAAqB,MAAM,KAAA,CAAM,CAAA,EAAG,UAAU,CAAA,2CAAA,CAAA,EAA+C;AAAA,MACjG,MAAA,EAAQ,MAAA;AAAA,MACR,OAAA,EAAS;AAAA,QACP,cAAA,EAAgB,kBAAA;AAAA,QAChB,eAAA,EAAiB,UAAU,WAAW,CAAA,CAAA;AAAA,QACtC,WAAA,EAAa;AAAA,OACf;AAAA,MACA,IAAA,EAAM,KAAK,SAAA,CAAU;AAAA,QACnB,WAAW,MAAA,CAAO,SAAA;AAAA,QAClB,QAAA;AAAA,QACA,aAAA,EAAe;AAAA,UACb,CAAA,EAAI,aAAA,CAAsB,CAAA,CAAE,QAAA,EAAS;AAAA,UACrC,CAAA,EAAI,aAAA,CAAsB,CAAA,CAAE,QAAA,EAAS;AAAA,UACrC,UAAW,aAAA,CAAsB;AAAA;AACnC,OACD;AAAA,KACF,CAAA;AAED,IAAA,IAAI,CAAC,mBAAmB,EAAA,EAAI;AAC1B,MAAA,MAAM,SAAA,GAAY,MAAM,kBAAA,CAAmB,IAAA,EAAK;AAChD,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,iCAAA,EAAiC,SAAS,CAAA,CAAE,CAAA;AAAA,IAC9D;AAEA,IAAA,MAAM,MAAA,GAAS,MAAM,kBAAA,CAAmB,IAAA,EAAK;AAE7C,IAAA,IAAI,CAAC,OAAO,eAAA,EAAiB;AAC3B,MAAA,MAAM,IAAI,MAAM,uDAAoD,CAAA;AAAA,IACtE;AAEA,IAAA,OAAO,MAAA,CAAO,eAAA;AAAA,EAChB,SAAS,KAAA,EAAO;AACd,IAAA,OAAA,CAAQ,KAAA,CAAM,4CAA4C,KAAK,CAAA;AAC/D,IAAA,MAAM,KAAA;AAAA,EACR;AACF,CAAA;;;ACvFO,IAAM,oBAAN,MAAwB;AAAA,EAC7B,YAAoB,MAAA,EAAqB;AAArB,IAAA,IAAA,CAAA,MAAA,GAAA,MAAA;AAAA,EAAsB;AAAA;AAAA;AAAA;AAAA,EAI1C,MAAM,mBACJ,MAAA,EACiB;AACjB,IAAA,OAAO,2BAAA,CAA4B;AAAA,MACjC,GAAG,MAAA;AAAA,MACH,YAAA,EAAc,IAAA,CAAK,MAAA,CAAO,eAAA,EAAgB;AAAA,MAC1C,UAAA,EAAY,KAAK,MAAA,CAAO;AAAA,KACzB,CAAA;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,SAAS,MAAA,EAQK;AAClB,IAAA,MAAM,eAAA,GAAkB,YAAA,CAAa,MAAA,CAAO,MAAA,EAAQ,OAAO,QAAQ,CAAA;AACnE,IAAA,OAAO,KAAK,kBAAA,CAAmB;AAAA,MAC7B,YAAY,MAAA,CAAO,UAAA;AAAA,MACnB,QAAQ,MAAA,CAAO,MAAA;AAAA,MACf,aAAa,MAAA,CAAO,WAAA;AAAA,MACpB,KAAA,EAAO;AAAA,QACL;AAAA,UACE,iBAAiB,MAAA,CAAO,eAAA;AAAA,UACxB,UAAA,EAAY,UAAA;AAAA,UACZ,QAAA,EAAU;AAAA,YACR,MAAA,CAAO,SAAA;AAAA,YACP,eAAA;AAAA,YACA;AAAA;AACF;AACF;AACF,KACD,CAAA;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,QAAQ,MAAA,EAQM;AAClB,IAAA,MAAM,eAAA,GAAkB,YAAA,CAAa,MAAA,CAAO,MAAA,EAAQ,OAAO,QAAQ,CAAA;AAEnE,IAAA,OAAO,KAAK,kBAAA,CAAmB;AAAA,MAC7B,YAAY,MAAA,CAAO,UAAA;AAAA,MACnB,QAAQ,MAAA,CAAO,MAAA;AAAA,MACf,aAAa,MAAA,CAAO,WAAA;AAAA,MACpB,KAAA,EAAO;AAAA,QACL;AAAA,UACE,iBAAiB,MAAA,CAAO,eAAA;AAAA,UACxB,UAAA,EAAY,SAAA;AAAA,UACZ,QAAA,EAAU;AAAA,YACR,MAAA,CAAO,OAAA;AAAA,YACP,eAAA;AAAA,YACA;AAAA;AACF;AACF;AACF,KACD,CAAA;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,gBAAgB,MAAA,EAKF;AAClB,IAAA,OAAO,KAAK,kBAAA,CAAmB;AAAA,MAC7B,YAAY,MAAA,CAAO,UAAA;AAAA,MACnB,QAAQ,MAAA,CAAO,MAAA;AAAA,MACf,aAAa,MAAA,CAAO,WAAA;AAAA,MACpB,OAAO,MAAA,CAAO;AAAA,KACf,CAAA;AAAA,EACH;AACF","file":"transactions.mjs","sourcesContent":["import CryptoJS from \"crypto-js\";\n\nexport const encryptPrivateKey = (\n privateKey: string,\n password: string,\n): string => {\n if (!privateKey || !password) {\n throw new Error(\"Private key and password are required\");\n }\n\n return CryptoJS.AES.encrypt(privateKey, password).toString();\n};\n\nexport const decryptPrivateKey = (\n encryptedPrivateKey: string,\n password: string,\n): string | null => {\n if (!encryptedPrivateKey || !password) {\n console.error(\"Encrypted private key and password are required\");\n return null;\n }\n\n try {\n const bytes = CryptoJS.AES.decrypt(encryptedPrivateKey, password);\n const decrypted = bytes.toString(CryptoJS.enc.Utf8);\n\n // Check if the decrypted string is empty\n if (!decrypted) {\n return null;\n }\n\n return decrypted;\n } catch (error) {\n console.error(\"Decryption failed:\", error);\n return null;\n }\n};\n","import type { ExecuteSponsoredTransactionResponse, ExecuteTransactionParams } from '@chipi-stack/types';\nimport { Account, RpcProvider, TypedData } from 'starknet';\nimport { decryptPrivateKey } from './lib';\n\n// This will need to be imported from the actual gasless SDK or implemented\n// For now, this is a placeholder implementation based on the original SDK\n\n/**\n * Execute a paymaster transaction (gasless)\n */\nexport const executePaymasterTransaction = async (\n params: ExecuteTransactionParams & {backendUrl: string} // Backend url shit is temporary\n): Promise<string> => {\n try {\n const { encryptKey, wallet, calls, apiPublicKey, bearerToken,backendUrl } = params;\n\n // Fetch the encrypted private key from clerk public metadata\n const privateKeyDecrypted = decryptPrivateKey(\n wallet.encryptedPrivateKey,\n encryptKey\n );\n\n if (!privateKeyDecrypted) {\n throw new Error(\"Failed to decrypt private key\");\n }\n\n const provider = new RpcProvider({\n nodeUrl: \"https://cloud.argent-api.com/v1/starknet/mainnet/rpc/v0.7\",\n });\n\n const account = new Account(\n provider,\n wallet.publicKey,\n privateKeyDecrypted\n );\n\n // Build the type data\n const typeDataResponse = await fetch(`${backendUrl}/transactions/prepare-typed-data`, {\n method: \"POST\",\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${bearerToken}`,\n 'X-API-Key': apiPublicKey,\n },\n body: JSON.stringify({\n publicKey: wallet.publicKey,\n calls: calls,\n accountClassHash: \"0x036078334509b514626504edc9fb252328d1a240e4e948bef8d0c08dff45927f\"\n }),\n });\n\n if (!typeDataResponse.ok) {\n const errorText = await typeDataResponse.text();\n throw new Error(`Error en la API: ${errorText}`);\n }\n\n const typeData = await typeDataResponse.json() as TypedData;\n\n // Sign the message\n const userSignature = await account.signMessage(typeData);\n\n \n // Execute the transaction\n const executeTransaction = await fetch(`${backendUrl}/transactions/execute-sponsored-transaction`, {\n method: \"POST\",\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${bearerToken}`,\n 'X-API-Key': apiPublicKey,\n },\n body: JSON.stringify({\n publicKey: wallet.publicKey,\n typeData: typeData,\n userSignature: {\n r: (userSignature as any).r.toString(),\n s: (userSignature as any).s.toString(),\n recovery: (userSignature as any).recovery\n }\n }),\n });\n\n if (!executeTransaction.ok) {\n const errorText = await executeTransaction.text();\n throw new Error(`Error en la API de ejecución: ${errorText}`);\n }\n\n const result = await executeTransaction.json() as ExecuteSponsoredTransactionResponse;\n \n if (!result.transactionHash) {\n throw new Error('La respuesta no contiene el hash de la transacción');\n }\n\n return result.transactionHash;\n } catch (error) {\n console.error(\"Error sending transaction with paymaster\", error);\n throw error;\n }\n};\n\n","import type {\n ExecuteTransactionParams,\n} from '@chipi-stack/types';\nimport { formatAmount } from '@chipi-stack/shared';\nimport { ChipiClient } from './client';\nimport { executePaymasterTransaction } from './gasless';\n\n/**\n * Transaction management utilities\n */\nexport class ChipiTransactions {\n constructor(private client: ChipiClient) {}\n /**\n * Execute a gasless transaction using paymaster\n */\n async executeTransaction(\n params: Omit<ExecuteTransactionParams, 'apiPublicKey'>\n ): Promise<string> {\n return executePaymasterTransaction({\n ...params,\n apiPublicKey: this.client.getApiPublicKey(),\n backendUrl: this.client.baseUrl,\n });\n }\n\n /**\n * Transfer tokens\n */\n async transfer(params: {\n encryptKey: string;\n wallet: any;\n contractAddress: string;\n recipient: string;\n amount: string | number;\n decimals?: number;\n bearerToken: string;\n }): Promise<string> {\n const formattedAmount = formatAmount(params.amount, params.decimals);\n return this.executeTransaction({\n encryptKey: params.encryptKey,\n wallet: params.wallet,\n bearerToken: params.bearerToken,\n calls: [\n {\n contractAddress: params.contractAddress,\n entrypoint: 'transfer',\n calldata: [\n params.recipient,\n formattedAmount,\n '0x0',\n ],\n },\n ],\n });\n }\n\n /**\n * Approve token spending\n */\n async approve(params: {\n encryptKey: string;\n wallet: any;\n contractAddress: string;\n spender: string;\n amount: string | number;\n decimals?: number;\n bearerToken: string;\n }): Promise<string> {\n const formattedAmount = formatAmount(params.amount, params.decimals);\n \n return this.executeTransaction({\n encryptKey: params.encryptKey,\n wallet: params.wallet,\n bearerToken: params.bearerToken,\n calls: [\n {\n contractAddress: params.contractAddress,\n entrypoint: 'approve',\n calldata: [\n params.spender,\n formattedAmount,\n '0x0',\n ],\n },\n ],\n });\n }\n\n /**\n * Call any contract method\n */\n async callAnyContract(params: {\n encryptKey: string;\n wallet: any;\n calls: any[];\n bearerToken: string;\n }): Promise<string> {\n return this.executeTransaction({\n encryptKey: params.encryptKey,\n wallet: params.wallet,\n bearerToken: params.bearerToken,\n calls: params.calls,\n });\n }\n}\n"]}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { CreateWalletParams, CreateWalletResponse, CreateCustodialWalletParams, WalletData, GetMerchantWalletParams, PaginationQuery, PaginatedResponse } from '@chipi-stack/types';
|
|
2
|
+
import { C as ChipiClient } from './client-3HAMR0rB.mjs';
|
|
3
|
+
import '@chipi-stack/shared';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Wallet management utilities
|
|
7
|
+
*/
|
|
8
|
+
declare class ChipiWallets {
|
|
9
|
+
private client;
|
|
10
|
+
constructor(client: ChipiClient);
|
|
11
|
+
/**
|
|
12
|
+
* Prepare wallet creation data
|
|
13
|
+
*/
|
|
14
|
+
/**
|
|
15
|
+
* Create a new wallet
|
|
16
|
+
*/
|
|
17
|
+
createWallet(params: CreateWalletParams & {
|
|
18
|
+
backendUrl: string;
|
|
19
|
+
}): Promise<CreateWalletResponse>;
|
|
20
|
+
encryptPrivateKey: (privateKey: string, password: string) => string;
|
|
21
|
+
/**
|
|
22
|
+
* Create a custodial merchant wallet
|
|
23
|
+
*/
|
|
24
|
+
createCustodialWallet(params: Omit<CreateCustodialWalletParams, 'orgId'>, orgId: string): Promise<WalletData>;
|
|
25
|
+
/**
|
|
26
|
+
* Get merchant wallet by API key and chain
|
|
27
|
+
*/
|
|
28
|
+
getMerchantWallet(params: GetMerchantWalletParams): Promise<WalletData>;
|
|
29
|
+
/**
|
|
30
|
+
* Get wallets for an organization
|
|
31
|
+
*/
|
|
32
|
+
getWallets(query: PaginationQuery & {
|
|
33
|
+
apiKeyId: string;
|
|
34
|
+
orgId: string;
|
|
35
|
+
}): Promise<PaginatedResponse<WalletData>>;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export { ChipiWallets };
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { CreateWalletParams, CreateWalletResponse, CreateCustodialWalletParams, WalletData, GetMerchantWalletParams, PaginationQuery, PaginatedResponse } from '@chipi-stack/types';
|
|
2
|
+
import { C as ChipiClient } from './client-3HAMR0rB.js';
|
|
3
|
+
import '@chipi-stack/shared';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Wallet management utilities
|
|
7
|
+
*/
|
|
8
|
+
declare class ChipiWallets {
|
|
9
|
+
private client;
|
|
10
|
+
constructor(client: ChipiClient);
|
|
11
|
+
/**
|
|
12
|
+
* Prepare wallet creation data
|
|
13
|
+
*/
|
|
14
|
+
/**
|
|
15
|
+
* Create a new wallet
|
|
16
|
+
*/
|
|
17
|
+
createWallet(params: CreateWalletParams & {
|
|
18
|
+
backendUrl: string;
|
|
19
|
+
}): Promise<CreateWalletResponse>;
|
|
20
|
+
encryptPrivateKey: (privateKey: string, password: string) => string;
|
|
21
|
+
/**
|
|
22
|
+
* Create a custodial merchant wallet
|
|
23
|
+
*/
|
|
24
|
+
createCustodialWallet(params: Omit<CreateCustodialWalletParams, 'orgId'>, orgId: string): Promise<WalletData>;
|
|
25
|
+
/**
|
|
26
|
+
* Get merchant wallet by API key and chain
|
|
27
|
+
*/
|
|
28
|
+
getMerchantWallet(params: GetMerchantWalletParams): Promise<WalletData>;
|
|
29
|
+
/**
|
|
30
|
+
* Get wallets for an organization
|
|
31
|
+
*/
|
|
32
|
+
getWallets(query: PaginationQuery & {
|
|
33
|
+
apiKeyId: string;
|
|
34
|
+
orgId: string;
|
|
35
|
+
}): Promise<PaginatedResponse<WalletData>>;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export { ChipiWallets };
|
package/dist/wallets.js
ADDED
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var shared = require('@chipi-stack/shared');
|
|
4
|
+
var starknet = require('starknet');
|
|
5
|
+
var CryptoJS = require('crypto-js');
|
|
6
|
+
|
|
7
|
+
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
8
|
+
|
|
9
|
+
var CryptoJS__default = /*#__PURE__*/_interopDefault(CryptoJS);
|
|
10
|
+
|
|
11
|
+
// src/wallets.ts
|
|
12
|
+
var ChipiWallets = class {
|
|
13
|
+
constructor(client) {
|
|
14
|
+
this.client = client;
|
|
15
|
+
this.encryptPrivateKey = (privateKey, password) => {
|
|
16
|
+
if (!privateKey || !password) {
|
|
17
|
+
throw new Error("Private key and password are required");
|
|
18
|
+
}
|
|
19
|
+
return CryptoJS__default.default.AES.encrypt(privateKey, password).toString();
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Prepare wallet creation data
|
|
24
|
+
*/
|
|
25
|
+
// async prepareWalletCreation(
|
|
26
|
+
// params: Omit<PrepareWalletCreationParams, 'apiPublicKey'>
|
|
27
|
+
// ): Promise<PrepareWalletCreationResponse> {
|
|
28
|
+
// const response = await this.client.post<PrepareWalletCreationResponse>(
|
|
29
|
+
// `${API_ENDPOINTS.CHIPI_WALLETS}/prepare-creation`,
|
|
30
|
+
// params
|
|
31
|
+
// );
|
|
32
|
+
// return response.data!;
|
|
33
|
+
// }
|
|
34
|
+
/**
|
|
35
|
+
* Create a new wallet
|
|
36
|
+
*/
|
|
37
|
+
// async createWallet(
|
|
38
|
+
// params: Omit<CreateWalletParams, 'apiPublicKey' | 'nodeUrl'>,
|
|
39
|
+
// nodeUrl?: string
|
|
40
|
+
// ): Promise<CreateWalletResponse> {
|
|
41
|
+
// const response = await this.client.post<CreateWalletResponse>(
|
|
42
|
+
// API_ENDPOINTS.CHIPI_WALLETS,
|
|
43
|
+
// {
|
|
44
|
+
// ...params,
|
|
45
|
+
// nodeUrl,
|
|
46
|
+
// },
|
|
47
|
+
// params.bearerToken
|
|
48
|
+
// );
|
|
49
|
+
// return response.data!;
|
|
50
|
+
// }
|
|
51
|
+
async createWallet(params) {
|
|
52
|
+
try {
|
|
53
|
+
const { encryptKey, apiPublicKey, bearerToken, nodeUrl, backendUrl } = params;
|
|
54
|
+
const provider = new starknet.RpcProvider({ nodeUrl });
|
|
55
|
+
const privateKeyAX = starknet.stark.randomAddress();
|
|
56
|
+
const starkKeyPubAX = starknet.ec.starkCurve.getStarkKey(privateKeyAX);
|
|
57
|
+
const accountClassHash = "0x036078334509b514626504edc9fb252328d1a240e4e948bef8d0c08dff45927f";
|
|
58
|
+
const axSigner = new starknet.CairoCustomEnum({
|
|
59
|
+
Starknet: { pubkey: starkKeyPubAX }
|
|
60
|
+
});
|
|
61
|
+
const axGuardian = new starknet.CairoOption(starknet.CairoOptionVariant.None);
|
|
62
|
+
const AXConstructorCallData = starknet.CallData.compile({
|
|
63
|
+
owner: axSigner,
|
|
64
|
+
guardian: axGuardian
|
|
65
|
+
});
|
|
66
|
+
const publicKey = starknet.hash.calculateContractAddressFromHash(
|
|
67
|
+
starkKeyPubAX,
|
|
68
|
+
accountClassHash,
|
|
69
|
+
AXConstructorCallData,
|
|
70
|
+
0
|
|
71
|
+
);
|
|
72
|
+
const account = new starknet.Account(provider, publicKey, privateKeyAX);
|
|
73
|
+
console.log("apiPublicKey", apiPublicKey);
|
|
74
|
+
const typeDataResponse = await fetch(`${backendUrl}/chipi-wallets/prepare-creation`, {
|
|
75
|
+
method: "POST",
|
|
76
|
+
headers: {
|
|
77
|
+
"Content-Type": "application/json",
|
|
78
|
+
"Authorization": `Bearer ${bearerToken}`,
|
|
79
|
+
"x-api-key": apiPublicKey
|
|
80
|
+
},
|
|
81
|
+
body: JSON.stringify({
|
|
82
|
+
publicKey
|
|
83
|
+
})
|
|
84
|
+
});
|
|
85
|
+
const { typeData, accountClassHash: accountClassHashResponse } = await typeDataResponse.json();
|
|
86
|
+
const userSignature = await account.signMessage(typeData);
|
|
87
|
+
const deploymentData = {
|
|
88
|
+
class_hash: accountClassHashResponse,
|
|
89
|
+
salt: starkKeyPubAX,
|
|
90
|
+
unique: `${starknet.num.toHex(0)}`,
|
|
91
|
+
calldata: AXConstructorCallData.map((value) => starknet.num.toHex(value))
|
|
92
|
+
};
|
|
93
|
+
const encryptedPrivateKey = this.encryptPrivateKey(privateKeyAX, encryptKey);
|
|
94
|
+
const executeTransactionResponse = await fetch(`${backendUrl}/chipi-wallets`, {
|
|
95
|
+
method: "POST",
|
|
96
|
+
headers: {
|
|
97
|
+
"Content-Type": "application/json",
|
|
98
|
+
"Authorization": `Bearer ${bearerToken}`,
|
|
99
|
+
"x-api-key": apiPublicKey
|
|
100
|
+
},
|
|
101
|
+
body: JSON.stringify({
|
|
102
|
+
apiPublicKey,
|
|
103
|
+
publicKey,
|
|
104
|
+
userSignature: {
|
|
105
|
+
r: userSignature.r.toString(),
|
|
106
|
+
s: userSignature.s.toString(),
|
|
107
|
+
recovery: userSignature.recovery
|
|
108
|
+
},
|
|
109
|
+
typeData,
|
|
110
|
+
encryptedPrivateKey,
|
|
111
|
+
deploymentData: {
|
|
112
|
+
...deploymentData,
|
|
113
|
+
salt: `${deploymentData.salt}`,
|
|
114
|
+
calldata: deploymentData.calldata.map((data) => `${data}`)
|
|
115
|
+
}
|
|
116
|
+
})
|
|
117
|
+
});
|
|
118
|
+
const executeTransaction = await executeTransactionResponse.json();
|
|
119
|
+
if (executeTransaction.success) {
|
|
120
|
+
return {
|
|
121
|
+
success: true,
|
|
122
|
+
txHash: executeTransaction.txHash,
|
|
123
|
+
walletPublicKey: executeTransaction.walletPublicKey,
|
|
124
|
+
wallet: executeTransaction.wallet
|
|
125
|
+
};
|
|
126
|
+
} else {
|
|
127
|
+
return {
|
|
128
|
+
success: false,
|
|
129
|
+
txHash: "",
|
|
130
|
+
walletPublicKey: "",
|
|
131
|
+
wallet: {
|
|
132
|
+
publicKey: "",
|
|
133
|
+
encryptedPrivateKey: ""
|
|
134
|
+
}
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
} catch (error) {
|
|
138
|
+
console.error("Error detallado:", error);
|
|
139
|
+
if (error instanceof Error && error.message.includes("SSL")) {
|
|
140
|
+
throw new Error(
|
|
141
|
+
"Error de conexi\xF3n SSL. Intenta usando NODE_TLS_REJECT_UNAUTHORIZED=0 o verifica la URL del RPC"
|
|
142
|
+
);
|
|
143
|
+
}
|
|
144
|
+
throw new shared.ChipiTransactionError(
|
|
145
|
+
`Failed to create wallet: ${error instanceof Error ? error.message : "Unknown error"}`,
|
|
146
|
+
"WALLET_CREATION_FAILED"
|
|
147
|
+
);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Create a custodial merchant wallet
|
|
152
|
+
*/
|
|
153
|
+
async createCustodialWallet(params, orgId) {
|
|
154
|
+
const response = await this.client.post(
|
|
155
|
+
`${shared.API_ENDPOINTS.CHIPI_WALLETS}/merchant`,
|
|
156
|
+
{
|
|
157
|
+
...params,
|
|
158
|
+
orgId
|
|
159
|
+
}
|
|
160
|
+
);
|
|
161
|
+
return response.data;
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Get merchant wallet by API key and chain
|
|
165
|
+
*/
|
|
166
|
+
async getMerchantWallet(params) {
|
|
167
|
+
const response = await this.client.get(
|
|
168
|
+
`${shared.API_ENDPOINTS.CHIPI_WALLETS}/merchant`,
|
|
169
|
+
{
|
|
170
|
+
apiKeyId: params.apiKeyId,
|
|
171
|
+
chain: params.chain
|
|
172
|
+
}
|
|
173
|
+
);
|
|
174
|
+
return response.data;
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Get wallets for an organization
|
|
178
|
+
*/
|
|
179
|
+
async getWallets(query) {
|
|
180
|
+
const response = await this.client.get(
|
|
181
|
+
shared.API_ENDPOINTS.CHIPI_WALLETS,
|
|
182
|
+
query
|
|
183
|
+
);
|
|
184
|
+
return response.data;
|
|
185
|
+
}
|
|
186
|
+
};
|
|
187
|
+
|
|
188
|
+
exports.ChipiWallets = ChipiWallets;
|
|
189
|
+
//# sourceMappingURL=wallets.js.map
|
|
190
|
+
//# sourceMappingURL=wallets.js.map
|