@opensea/wallet-adapters 0.2.1 → 0.3.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 +38 -0
- package/dist/ethers.d.ts +1 -1
- package/dist/{index-DFTwYt_e.d.ts → index-jjHnOuwA.d.ts} +65 -2
- package/dist/index.d.ts +181 -13
- package/dist/index.js +173 -60
- package/dist/index.js.map +1 -1
- package/dist/viem.d.ts +1 -1
- package/package.json +6 -1
package/dist/index.js
CHANGED
|
@@ -51,6 +51,14 @@ var BankrAdapter = class _BankrAdapter {
|
|
|
51
51
|
this.cachedAddress = evmWallet.address;
|
|
52
52
|
return evmWallet.address;
|
|
53
53
|
}
|
|
54
|
+
async getWalletInfo() {
|
|
55
|
+
const address = await this.getAddress();
|
|
56
|
+
return {
|
|
57
|
+
provider: "bankr",
|
|
58
|
+
address,
|
|
59
|
+
scopeIntrospectable: false
|
|
60
|
+
};
|
|
61
|
+
}
|
|
54
62
|
async sendTransaction(tx) {
|
|
55
63
|
this.onRequest?.("sendTransaction", tx);
|
|
56
64
|
const startTime = Date.now();
|
|
@@ -413,6 +421,15 @@ var FireblocksAdapter = class _FireblocksAdapter {
|
|
|
413
421
|
this.cachedAddress = data[0].address;
|
|
414
422
|
return data[0].address;
|
|
415
423
|
}
|
|
424
|
+
async getWalletInfo() {
|
|
425
|
+
const address = await this.getAddress();
|
|
426
|
+
return {
|
|
427
|
+
provider: "fireblocks",
|
|
428
|
+
address,
|
|
429
|
+
vaultId: this.config.vaultId,
|
|
430
|
+
roleIntrospectable: false
|
|
431
|
+
};
|
|
432
|
+
}
|
|
416
433
|
async sendTransaction(tx) {
|
|
417
434
|
this.onRequest?.("sendTransaction", tx);
|
|
418
435
|
const startTime = Date.now();
|
|
@@ -703,6 +720,38 @@ var TurnkeyAdapter = class _TurnkeyAdapter {
|
|
|
703
720
|
async getAddress() {
|
|
704
721
|
return this.config.walletAddress;
|
|
705
722
|
}
|
|
723
|
+
async getWalletInfo() {
|
|
724
|
+
const whoamiResponse = await this.signedRequest("/public/v1/query/whoami", {
|
|
725
|
+
organizationId: this.config.organizationId
|
|
726
|
+
});
|
|
727
|
+
if (!whoamiResponse.ok) {
|
|
728
|
+
const body = await whoamiResponse.text();
|
|
729
|
+
throw new Error(
|
|
730
|
+
`Turnkey getWalletInfo whoami failed (${whoamiResponse.status}): ${body}`
|
|
731
|
+
);
|
|
732
|
+
}
|
|
733
|
+
const whoami = await whoamiResponse.json();
|
|
734
|
+
const orgResponse = await this.signedRequest(
|
|
735
|
+
"/public/v1/query/get_organization",
|
|
736
|
+
{ organizationId: this.config.organizationId }
|
|
737
|
+
);
|
|
738
|
+
if (!orgResponse.ok) {
|
|
739
|
+
const body = await orgResponse.text();
|
|
740
|
+
throw new Error(
|
|
741
|
+
`Turnkey getWalletInfo get_organization failed (${orgResponse.status}): ${body}`
|
|
742
|
+
);
|
|
743
|
+
}
|
|
744
|
+
const orgData = await orgResponse.json();
|
|
745
|
+
const rootUserIds = orgData.organizationData?.rootQuorum?.userIds ?? [];
|
|
746
|
+
return {
|
|
747
|
+
provider: "turnkey",
|
|
748
|
+
address: this.config.walletAddress,
|
|
749
|
+
organizationId: whoami.organizationId,
|
|
750
|
+
userId: whoami.userId,
|
|
751
|
+
username: whoami.username ?? "",
|
|
752
|
+
isRootUser: rootUserIds.includes(whoami.userId)
|
|
753
|
+
};
|
|
754
|
+
}
|
|
706
755
|
async sendTransaction(tx) {
|
|
707
756
|
this.onRequest?.("sendTransaction", tx);
|
|
708
757
|
const startTime = Date.now();
|
|
@@ -1072,9 +1121,6 @@ var PrivateKeyAdapter = class _PrivateKeyAdapter {
|
|
|
1072
1121
|
if (!privateKey) {
|
|
1073
1122
|
throw new Error("PRIVATE_KEY environment variable is required");
|
|
1074
1123
|
}
|
|
1075
|
-
if (!rpcUrl) {
|
|
1076
|
-
throw new Error("RPC_URL environment variable is required");
|
|
1077
|
-
}
|
|
1078
1124
|
const clean = privateKey.startsWith("0x") ? privateKey.slice(2) : privateKey;
|
|
1079
1125
|
if (!/^[0-9a-fA-F]{64}$/.test(clean)) {
|
|
1080
1126
|
throw new Error(
|
|
@@ -1102,7 +1148,12 @@ var PrivateKeyAdapter = class _PrivateKeyAdapter {
|
|
|
1102
1148
|
this.onRequest?.("sendTransaction", tx);
|
|
1103
1149
|
const startTime = Date.now();
|
|
1104
1150
|
const from = await this.getAddress();
|
|
1105
|
-
const
|
|
1151
|
+
const rpcUrl = this.config.rpcUrl;
|
|
1152
|
+
if (!rpcUrl) {
|
|
1153
|
+
throw new Error(
|
|
1154
|
+
"RPC_URL is required for sending transactions. Set the RPC_URL environment variable or pass --rpc-url."
|
|
1155
|
+
);
|
|
1156
|
+
}
|
|
1106
1157
|
let nonce;
|
|
1107
1158
|
let gasLimit;
|
|
1108
1159
|
let maxFeePerGas;
|
|
@@ -1290,6 +1341,7 @@ function encodeEcdsaSignature(r, s, v) {
|
|
|
1290
1341
|
|
|
1291
1342
|
// src/adapters/privy.ts
|
|
1292
1343
|
var PRIVY_API_BASE = "https://api.privy.io";
|
|
1344
|
+
var PRIVY_401_ECHO_HINT = ` (hint: if you're verifying credentials via curl, use 'printf %s "$PRIVY_APP_ID:$PRIVY_APP_SECRET" | base64' \u2014 'echo' adds a trailing newline that breaks basic auth)`;
|
|
1293
1345
|
var PrivyAdapter = class _PrivyAdapter {
|
|
1294
1346
|
name = "privy";
|
|
1295
1347
|
capabilities = {
|
|
@@ -1322,13 +1374,14 @@ var PrivyAdapter = class _PrivyAdapter {
|
|
|
1322
1374
|
appId,
|
|
1323
1375
|
appSecret,
|
|
1324
1376
|
walletId,
|
|
1325
|
-
baseUrl: process.env.PRIVY_API_BASE_URL
|
|
1377
|
+
baseUrl: process.env.PRIVY_API_BASE_URL,
|
|
1378
|
+
authSigningKey: process.env.PRIVY_AUTH_SIGNING_KEY
|
|
1326
1379
|
});
|
|
1327
1380
|
}
|
|
1328
1381
|
get baseUrl() {
|
|
1329
1382
|
return this.config.baseUrl ?? PRIVY_API_BASE;
|
|
1330
1383
|
}
|
|
1331
|
-
get
|
|
1384
|
+
get basicAuthHeaders() {
|
|
1332
1385
|
const credentials = Buffer.from(
|
|
1333
1386
|
`${this.config.appId}:${this.config.appSecret}`
|
|
1334
1387
|
).toString("base64");
|
|
@@ -1338,46 +1391,105 @@ var PrivyAdapter = class _PrivyAdapter {
|
|
|
1338
1391
|
"Content-Type": "application/json"
|
|
1339
1392
|
};
|
|
1340
1393
|
}
|
|
1394
|
+
/**
|
|
1395
|
+
* Build headers for a POST /rpc call, including the authorization
|
|
1396
|
+
* signature when `authSigningKey` is configured. Lazy-imports
|
|
1397
|
+
* `@privy-io/node` so users who don't enable auth-key signing don't
|
|
1398
|
+
* need the optional peer dependency installed.
|
|
1399
|
+
*/
|
|
1400
|
+
async rpcHeaders(body, rpcUrl) {
|
|
1401
|
+
const headers = { ...this.basicAuthHeaders };
|
|
1402
|
+
if (!this.config.authSigningKey) return headers;
|
|
1403
|
+
let generateAuthorizationSignature;
|
|
1404
|
+
try {
|
|
1405
|
+
;
|
|
1406
|
+
({ generateAuthorizationSignature } = await import("@privy-io/node"));
|
|
1407
|
+
} catch (cause) {
|
|
1408
|
+
throw new Error(
|
|
1409
|
+
"PRIVY_AUTH_SIGNING_KEY is set but @privy-io/node is not installed. Install it with `pnpm add @privy-io/node` (or your package manager equivalent).",
|
|
1410
|
+
{ cause }
|
|
1411
|
+
);
|
|
1412
|
+
}
|
|
1413
|
+
const signature = generateAuthorizationSignature({
|
|
1414
|
+
authorizationPrivateKey: this.config.authSigningKey,
|
|
1415
|
+
input: {
|
|
1416
|
+
version: 1,
|
|
1417
|
+
method: "POST",
|
|
1418
|
+
url: rpcUrl,
|
|
1419
|
+
body,
|
|
1420
|
+
headers: { "privy-app-id": this.config.appId }
|
|
1421
|
+
}
|
|
1422
|
+
});
|
|
1423
|
+
headers["privy-authorization-signature"] = signature;
|
|
1424
|
+
return headers;
|
|
1425
|
+
}
|
|
1341
1426
|
async getAddress() {
|
|
1342
1427
|
if (this.cachedAddress) return this.cachedAddress;
|
|
1343
1428
|
const response = await fetch(
|
|
1344
1429
|
`${this.baseUrl}/v1/wallets/${this.config.walletId}`,
|
|
1345
|
-
{ headers: this.
|
|
1430
|
+
{ headers: this.basicAuthHeaders }
|
|
1346
1431
|
);
|
|
1347
1432
|
if (!response.ok) {
|
|
1348
1433
|
const body = await response.text();
|
|
1349
|
-
|
|
1434
|
+
const hint = response.status === 401 && body.includes("Invalid app ID or app secret") ? PRIVY_401_ECHO_HINT : "";
|
|
1435
|
+
throw new Error(
|
|
1436
|
+
`Privy getAddress failed (${response.status}): ${body}${hint}`
|
|
1437
|
+
);
|
|
1350
1438
|
}
|
|
1351
1439
|
const data = await response.json();
|
|
1352
1440
|
this.cachedAddress = data.address;
|
|
1353
1441
|
return data.address;
|
|
1354
1442
|
}
|
|
1443
|
+
async getWalletInfo() {
|
|
1444
|
+
const response = await fetch(
|
|
1445
|
+
`${this.baseUrl}/v1/wallets/${this.config.walletId}`,
|
|
1446
|
+
{ headers: this.basicAuthHeaders }
|
|
1447
|
+
);
|
|
1448
|
+
if (!response.ok) {
|
|
1449
|
+
const body = await response.text();
|
|
1450
|
+
const hint = response.status === 401 && body.includes("Invalid app ID or app secret") ? PRIVY_401_ECHO_HINT : "";
|
|
1451
|
+
throw new Error(
|
|
1452
|
+
`Privy getWalletInfo failed (${response.status}): ${body}${hint}`
|
|
1453
|
+
);
|
|
1454
|
+
}
|
|
1455
|
+
const data = await response.json();
|
|
1456
|
+
this.cachedAddress = data.address;
|
|
1457
|
+
const ownerKeyId = data.owner_id ?? null;
|
|
1458
|
+
return {
|
|
1459
|
+
provider: "privy",
|
|
1460
|
+
address: data.address,
|
|
1461
|
+
chainType: data.chain_type,
|
|
1462
|
+
policyIds: data.policy_ids ?? [],
|
|
1463
|
+
ownerKeyId,
|
|
1464
|
+
additionalSignerCount: data.additional_signers?.length ?? 0,
|
|
1465
|
+
ownerEnforcesAuthKey: ownerKeyId !== null
|
|
1466
|
+
};
|
|
1467
|
+
}
|
|
1355
1468
|
async sendTransaction(tx) {
|
|
1356
1469
|
this.onRequest?.("sendTransaction", tx);
|
|
1357
1470
|
const startTime = Date.now();
|
|
1358
1471
|
const caip2 = `eip155:${tx.chainId}`;
|
|
1359
|
-
const
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
to: tx.to,
|
|
1370
|
-
data: tx.data,
|
|
1371
|
-
value: tx.value
|
|
1372
|
-
}
|
|
1373
|
-
}
|
|
1374
|
-
})
|
|
1472
|
+
const rpcUrl = `${this.baseUrl}/v1/wallets/${this.config.walletId}/rpc`;
|
|
1473
|
+
const body = {
|
|
1474
|
+
method: "eth_sendTransaction",
|
|
1475
|
+
caip2,
|
|
1476
|
+
params: {
|
|
1477
|
+
transaction: {
|
|
1478
|
+
to: tx.to,
|
|
1479
|
+
data: tx.data,
|
|
1480
|
+
value: tx.value
|
|
1481
|
+
}
|
|
1375
1482
|
}
|
|
1376
|
-
|
|
1483
|
+
};
|
|
1484
|
+
const response = await fetch(rpcUrl, {
|
|
1485
|
+
method: "POST",
|
|
1486
|
+
headers: await this.rpcHeaders(body, rpcUrl),
|
|
1487
|
+
body: JSON.stringify(body)
|
|
1488
|
+
});
|
|
1377
1489
|
if (!response.ok) {
|
|
1378
|
-
const
|
|
1490
|
+
const responseBody = await response.text();
|
|
1379
1491
|
throw new Error(
|
|
1380
|
-
`Privy sendTransaction failed (${response.status}): ${
|
|
1492
|
+
`Privy sendTransaction failed (${response.status}): ${responseBody}`
|
|
1381
1493
|
);
|
|
1382
1494
|
}
|
|
1383
1495
|
const data = await response.json();
|
|
@@ -1388,21 +1500,23 @@ var PrivyAdapter = class _PrivyAdapter {
|
|
|
1388
1500
|
async signMessage(request) {
|
|
1389
1501
|
this.onRequest?.("signMessage", request);
|
|
1390
1502
|
const startTime = Date.now();
|
|
1391
|
-
const
|
|
1392
|
-
const
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
);
|
|
1503
|
+
const isBytes = typeof request.message !== "string";
|
|
1504
|
+
const message = isBytes ? `0x${Buffer.from(request.message).toString("hex")}` : request.message;
|
|
1505
|
+
const rpcUrl = `${this.baseUrl}/v1/wallets/${this.config.walletId}/rpc`;
|
|
1506
|
+
const body = {
|
|
1507
|
+
method: "personal_sign",
|
|
1508
|
+
params: { message, encoding: isBytes ? "hex" : "utf-8" }
|
|
1509
|
+
};
|
|
1510
|
+
const response = await fetch(rpcUrl, {
|
|
1511
|
+
method: "POST",
|
|
1512
|
+
headers: await this.rpcHeaders(body, rpcUrl),
|
|
1513
|
+
body: JSON.stringify(body)
|
|
1514
|
+
});
|
|
1403
1515
|
if (!response.ok) {
|
|
1404
|
-
const
|
|
1405
|
-
throw new Error(
|
|
1516
|
+
const responseBody = await response.text();
|
|
1517
|
+
throw new Error(
|
|
1518
|
+
`Privy signMessage failed (${response.status}): ${responseBody}`
|
|
1519
|
+
);
|
|
1406
1520
|
}
|
|
1407
1521
|
const data = await response.json();
|
|
1408
1522
|
this.onResponse?.(
|
|
@@ -1415,28 +1529,27 @@ var PrivyAdapter = class _PrivyAdapter {
|
|
|
1415
1529
|
async signTypedData(request) {
|
|
1416
1530
|
this.onRequest?.("signTypedData", request);
|
|
1417
1531
|
const startTime = Date.now();
|
|
1418
|
-
const
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
domain: request.domain,
|
|
1428
|
-
types: request.types,
|
|
1429
|
-
primaryType: request.primaryType,
|
|
1430
|
-
message: request.message
|
|
1431
|
-
})
|
|
1432
|
-
}
|
|
1532
|
+
const rpcUrl = `${this.baseUrl}/v1/wallets/${this.config.walletId}/rpc`;
|
|
1533
|
+
const body = {
|
|
1534
|
+
method: "eth_signTypedData_v4",
|
|
1535
|
+
params: {
|
|
1536
|
+
typedData: JSON.stringify({
|
|
1537
|
+
domain: request.domain,
|
|
1538
|
+
types: request.types,
|
|
1539
|
+
primaryType: request.primaryType,
|
|
1540
|
+
message: request.message
|
|
1433
1541
|
})
|
|
1434
1542
|
}
|
|
1435
|
-
|
|
1543
|
+
};
|
|
1544
|
+
const response = await fetch(rpcUrl, {
|
|
1545
|
+
method: "POST",
|
|
1546
|
+
headers: await this.rpcHeaders(body, rpcUrl),
|
|
1547
|
+
body: JSON.stringify(body)
|
|
1548
|
+
});
|
|
1436
1549
|
if (!response.ok) {
|
|
1437
|
-
const
|
|
1550
|
+
const responseBody = await response.text();
|
|
1438
1551
|
throw new Error(
|
|
1439
|
-
`Privy signTypedData failed (${response.status}): ${
|
|
1552
|
+
`Privy signTypedData failed (${response.status}): ${responseBody}`
|
|
1440
1553
|
);
|
|
1441
1554
|
}
|
|
1442
1555
|
const data = await response.json();
|
|
@@ -1467,7 +1580,7 @@ function createWalletFromEnv() {
|
|
|
1467
1580
|
return PrivateKeyAdapter.fromEnv();
|
|
1468
1581
|
}
|
|
1469
1582
|
throw new Error(
|
|
1470
|
-
"No wallet provider configured. Set environment variables for one of:\n \u2022 Privy: PRIVY_APP_ID, PRIVY_APP_SECRET, PRIVY_WALLET_ID\n \u2022 Fireblocks: FIREBLOCKS_API_KEY, FIREBLOCKS_API_SECRET, FIREBLOCKS_VAULT_ID\n \u2022 Turnkey: TURNKEY_API_PUBLIC_KEY, TURNKEY_API_PRIVATE_KEY, TURNKEY_ORGANIZATION_ID, TURNKEY_WALLET_ADDRESS, TURNKEY_RPC_URL\n \u2022 Bankr: BANKR_API_KEY\n \u2022 PrivateKey: PRIVATE_KEY
|
|
1583
|
+
"No wallet provider configured. Set environment variables for one of:\n \u2022 Privy: PRIVY_APP_ID, PRIVY_APP_SECRET, PRIVY_WALLET_ID\n \u2022 Fireblocks: FIREBLOCKS_API_KEY, FIREBLOCKS_API_SECRET, FIREBLOCKS_VAULT_ID\n \u2022 Turnkey: TURNKEY_API_PUBLIC_KEY, TURNKEY_API_PRIVATE_KEY, TURNKEY_ORGANIZATION_ID, TURNKEY_WALLET_ADDRESS, TURNKEY_RPC_URL\n \u2022 Bankr: BANKR_API_KEY\n \u2022 PrivateKey: PRIVATE_KEY (optionally RPC_URL for sending transactions)"
|
|
1471
1584
|
);
|
|
1472
1585
|
}
|
|
1473
1586
|
function createWalletForProvider(provider) {
|