@ardrive/turbo-sdk 1.33.1 → 1.34.0-alpha.2
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 +49 -6
- package/bundles/web.bundle.min.js +103598 -103276
- package/lib/cjs/cli/cli.js +1 -1
- package/lib/cjs/cli/commands/cryptoFund.js +3 -1
- package/lib/cjs/common/payment.js +17 -4
- package/lib/cjs/common/signer.js +16 -1
- package/lib/cjs/common/token/ario.js +27 -19
- package/lib/cjs/common/token/arweave.js +4 -1
- package/lib/cjs/common/token/baseEth.js +7 -6
- package/lib/cjs/common/token/erc20.js +91 -0
- package/lib/cjs/common/token/ethereum.js +38 -18
- package/lib/cjs/common/token/index.js +11 -0
- package/lib/cjs/common/token/polygon.js +7 -6
- package/lib/cjs/common/token/solana.js +11 -2
- package/lib/cjs/common/token/usdc.js +83 -0
- package/lib/cjs/common/upload.js +6 -1
- package/lib/cjs/types.js +3 -0
- package/lib/cjs/utils/common.js +71 -4
- package/lib/cjs/version.js +1 -1
- package/lib/esm/cli/cli.js +1 -1
- package/lib/esm/cli/commands/cryptoFund.js +3 -1
- package/lib/esm/common/payment.js +17 -4
- package/lib/esm/common/signer.js +17 -2
- package/lib/esm/common/token/ario.js +27 -19
- package/lib/esm/common/token/arweave.js +4 -1
- package/lib/esm/common/token/baseEth.js +6 -5
- package/lib/esm/common/token/erc20.js +87 -0
- package/lib/esm/common/token/ethereum.js +37 -18
- package/lib/esm/common/token/index.js +11 -0
- package/lib/esm/common/token/polygon.js +6 -5
- package/lib/esm/common/token/solana.js +11 -2
- package/lib/esm/common/token/usdc.js +76 -0
- package/lib/esm/common/upload.js +6 -1
- package/lib/esm/types.js +3 -0
- package/lib/esm/utils/common.js +66 -5
- package/lib/esm/version.js +1 -1
- package/lib/types/cli/commands/cryptoFund.d.ts.map +1 -1
- package/lib/types/cli/types.d.ts +1 -0
- package/lib/types/cli/types.d.ts.map +1 -1
- package/lib/types/common/payment.d.ts +1 -1
- package/lib/types/common/payment.d.ts.map +1 -1
- package/lib/types/common/signer.d.ts +2 -2
- package/lib/types/common/signer.d.ts.map +1 -1
- package/lib/types/common/token/ario.d.ts +1 -1
- package/lib/types/common/token/ario.d.ts.map +1 -1
- package/lib/types/common/token/arweave.d.ts +1 -1
- package/lib/types/common/token/arweave.d.ts.map +1 -1
- package/lib/types/common/token/baseEth.d.ts +5 -0
- package/lib/types/common/token/baseEth.d.ts.map +1 -1
- package/lib/types/common/token/erc20.d.ts +19 -0
- package/lib/types/common/token/erc20.d.ts.map +1 -0
- package/lib/types/common/token/ethereum.d.ts +4 -2
- package/lib/types/common/token/ethereum.d.ts.map +1 -1
- package/lib/types/common/token/index.d.ts.map +1 -1
- package/lib/types/common/token/polygon.d.ts +5 -0
- package/lib/types/common/token/polygon.d.ts.map +1 -1
- package/lib/types/common/token/solana.d.ts +2 -1
- package/lib/types/common/token/solana.d.ts.map +1 -1
- package/lib/types/common/token/usdc.d.ts +36 -0
- package/lib/types/common/token/usdc.d.ts.map +1 -0
- package/lib/types/common/upload.d.ts.map +1 -1
- package/lib/types/types.d.ts +8 -2
- package/lib/types/types.d.ts.map +1 -1
- package/lib/types/utils/common.d.ts +6 -0
- package/lib/types/utils/common.d.ts.map +1 -1
- package/lib/types/version.d.ts +1 -1
- package/lib/types/version.d.ts.map +1 -1
- package/package.json +1 -1
package/lib/cjs/cli/cli.js
CHANGED
|
@@ -41,7 +41,7 @@ const utils_js_1 = require("./utils.js");
|
|
|
41
41
|
(0, utils_js_1.applyOptions)(commander_1.program.command('top-up').description('Top up a Turbo address with Fiat'), [...options_js_1.walletOptions, options_js_1.optionMap.address, options_js_1.optionMap.value, options_js_1.optionMap.currency]).action(async (_commandOptions, command) => {
|
|
42
42
|
await (0, utils_js_1.runCommand)(command, index_js_1.topUp);
|
|
43
43
|
});
|
|
44
|
-
(0, utils_js_1.applyOptions)(commander_1.program.command('crypto-fund').description('Top up a wallet with crypto'), [...options_js_1.walletOptions, options_js_1.optionMap.value, options_js_1.optionMap.txId]).action(async (_commandOptions, command) => {
|
|
44
|
+
(0, utils_js_1.applyOptions)(commander_1.program.command('crypto-fund').description('Top up a wallet with crypto'), [...options_js_1.walletOptions, options_js_1.optionMap.value, options_js_1.optionMap.txId, options_js_1.optionMap.address]).action(async (_commandOptions, command) => {
|
|
45
45
|
await (0, utils_js_1.runCommand)(command, index_js_1.cryptoFund);
|
|
46
46
|
});
|
|
47
47
|
(0, utils_js_1.applyOptions)(commander_1.program.command('upload-folder').description('Upload a folder using Turbo'), options_js_1.uploadFolderOptions).action(async (_commandOptions, command) => {
|
|
@@ -28,6 +28,7 @@ const utils_js_1 = require("../utils.js");
|
|
|
28
28
|
async function cryptoFund(options) {
|
|
29
29
|
const value = options.value;
|
|
30
30
|
const txId = options.txId;
|
|
31
|
+
const address = options.address;
|
|
31
32
|
if (txId !== undefined) {
|
|
32
33
|
const turbo = factory_js_1.TurboFactory.unauthenticated((0, utils_js_1.configFromOptions)(options));
|
|
33
34
|
const result = await turbo.submitFundTransaction({ txId: txId });
|
|
@@ -47,7 +48,7 @@ async function cryptoFund(options) {
|
|
|
47
48
|
const { confirm } = await (0, prompts_1.default)({
|
|
48
49
|
type: 'confirm',
|
|
49
50
|
name: 'confirm',
|
|
50
|
-
message: `\nTransaction details:\n\n Amount: ${value} ${token}\n Target: ${targetWallet}\n Est Credits to receive: ${credits}\n Credit recipient: ${await turbo.signer.getNativeAddress()}\n Note: Network Dependent Gas Fees May Apply\n\nThis payment is non-refundable. Proceed with transaction?`,
|
|
51
|
+
message: `\nTransaction details:\n\n Amount: ${value} ${token}\n Target: ${targetWallet}\n Est Credits to receive: ${credits}\n Credit recipient: ${address ?? (await turbo.signer.getNativeAddress())}\n Note: Network Dependent Gas Fees May Apply\n\nThis payment is non-refundable. Proceed with transaction?`,
|
|
51
52
|
initial: true,
|
|
52
53
|
});
|
|
53
54
|
if (!confirm) {
|
|
@@ -57,6 +58,7 @@ async function cryptoFund(options) {
|
|
|
57
58
|
}
|
|
58
59
|
const result = await turbo.topUpWithTokens({
|
|
59
60
|
tokenAmount,
|
|
61
|
+
turboCreditDestinationAddress: address,
|
|
60
62
|
});
|
|
61
63
|
console.log('Sent crypto fund transaction: \n', JSON.stringify(result, null, 2));
|
|
62
64
|
}
|
|
@@ -18,6 +18,7 @@ exports.TurboAuthenticatedPaymentService = exports.TurboUnauthenticatedPaymentSe
|
|
|
18
18
|
*/
|
|
19
19
|
const bignumber_js_1 = require("bignumber.js");
|
|
20
20
|
const axiosClient_js_1 = require("../utils/axiosClient.js");
|
|
21
|
+
const common_js_1 = require("../utils/common.js");
|
|
21
22
|
const http_js_1 = require("./http.js");
|
|
22
23
|
const logger_js_1 = require("./logger.js");
|
|
23
24
|
const index_js_1 = require("./token/index.js");
|
|
@@ -151,31 +152,37 @@ class TurboUnauthenticatedPaymentService {
|
|
|
151
152
|
return {
|
|
152
153
|
id: response.creditedTransaction.transactionId,
|
|
153
154
|
quantity: response.creditedTransaction.transactionQuantity,
|
|
154
|
-
owner: response.creditedTransaction.
|
|
155
|
+
owner: response.creditedTransaction.transactionSenderAddress ??
|
|
156
|
+
response.creditedTransaction.destinationAddress,
|
|
155
157
|
winc: response.creditedTransaction.winstonCreditAmount,
|
|
156
158
|
token: response.creditedTransaction.tokenType,
|
|
157
159
|
status: 'confirmed',
|
|
158
160
|
block: response.creditedTransaction.blockHeight,
|
|
161
|
+
recipient: response.creditedTransaction.destinationAddress,
|
|
159
162
|
};
|
|
160
163
|
}
|
|
161
164
|
else if ('pendingTransaction' in response) {
|
|
162
165
|
return {
|
|
163
166
|
id: response.pendingTransaction.transactionId,
|
|
164
167
|
quantity: response.pendingTransaction.transactionQuantity,
|
|
165
|
-
owner: response.pendingTransaction.
|
|
168
|
+
owner: response.pendingTransaction.transactionSenderAddress ??
|
|
169
|
+
response.pendingTransaction.destinationAddress,
|
|
166
170
|
winc: response.pendingTransaction.winstonCreditAmount,
|
|
167
171
|
token: response.pendingTransaction.tokenType,
|
|
168
172
|
status: 'pending',
|
|
173
|
+
recipient: response.pendingTransaction.destinationAddress,
|
|
169
174
|
};
|
|
170
175
|
}
|
|
171
176
|
else if ('failedTransaction' in response) {
|
|
172
177
|
return {
|
|
173
178
|
id: response.failedTransaction.transactionId,
|
|
174
179
|
quantity: response.failedTransaction.transactionQuantity,
|
|
175
|
-
owner: response.failedTransaction.
|
|
180
|
+
owner: response.failedTransaction.transactionSenderAddress ??
|
|
181
|
+
response.failedTransaction.destinationAddress,
|
|
176
182
|
winc: response.failedTransaction.winstonCreditAmount,
|
|
177
183
|
token: response.failedTransaction.tokenType,
|
|
178
184
|
status: 'failed',
|
|
185
|
+
recipient: response.failedTransaction.destinationAddress,
|
|
179
186
|
};
|
|
180
187
|
}
|
|
181
188
|
throw new Error('Unknown response from payment service: ' + response);
|
|
@@ -271,10 +278,15 @@ class TurboAuthenticatedPaymentService extends TurboUnauthenticatedPaymentServic
|
|
|
271
278
|
}
|
|
272
279
|
return walletAddress;
|
|
273
280
|
}
|
|
274
|
-
async topUpWithTokens({ feeMultiplier = 1, tokenAmount: tokenAmountV, }) {
|
|
281
|
+
async topUpWithTokens({ feeMultiplier = 1, tokenAmount: tokenAmountV, turboCreditDestinationAddress, }) {
|
|
275
282
|
if (!this.tokenTools) {
|
|
276
283
|
throw new Error(`Token type not supported for crypto fund ${this.token}`);
|
|
277
284
|
}
|
|
285
|
+
if (turboCreditDestinationAddress !== undefined) {
|
|
286
|
+
if ((0, common_js_1.isAnyValidUserAddress)(turboCreditDestinationAddress) === false) {
|
|
287
|
+
throw new Error(`Invalid turboCreditDestinationAddress provided: ${turboCreditDestinationAddress}`);
|
|
288
|
+
}
|
|
289
|
+
}
|
|
278
290
|
const tokenAmount = new bignumber_js_1.BigNumber(tokenAmountV);
|
|
279
291
|
const target = await this.getTargetWalletForFund();
|
|
280
292
|
this.logger.debug('Funding account...', {
|
|
@@ -287,6 +299,7 @@ class TurboAuthenticatedPaymentService extends TurboUnauthenticatedPaymentServic
|
|
|
287
299
|
tokenAmount,
|
|
288
300
|
feeMultiplier,
|
|
289
301
|
signer: this.signer,
|
|
302
|
+
turboCreditDestinationAddress,
|
|
290
303
|
});
|
|
291
304
|
const txId = fundTx.id;
|
|
292
305
|
try {
|
package/lib/cjs/common/signer.js
CHANGED
|
@@ -34,6 +34,8 @@ const tweetnacl_1 = __importDefault(require("tweetnacl"));
|
|
|
34
34
|
const types_js_1 = require("../types.js");
|
|
35
35
|
const base64_js_1 = require("../utils/base64.js");
|
|
36
36
|
const logger_js_1 = require("./logger.js");
|
|
37
|
+
const ethereum_js_1 = require("./token/ethereum.js");
|
|
38
|
+
const solana_js_1 = require("./token/solana.js");
|
|
37
39
|
/**
|
|
38
40
|
* Abstract class for signing TurboDataItems.
|
|
39
41
|
*/
|
|
@@ -52,6 +54,9 @@ class TurboDataItemAbstractSigner {
|
|
|
52
54
|
case 'matic':
|
|
53
55
|
case 'pol':
|
|
54
56
|
case 'base-eth':
|
|
57
|
+
case 'usdc':
|
|
58
|
+
case 'base-usdc':
|
|
59
|
+
case 'polygon-usdc':
|
|
55
60
|
return (0, ethers_2.computeAddress)((0, signing_key_1.computePublicKey)((0, base64_js_1.fromB64Url)(owner)));
|
|
56
61
|
case 'kyve':
|
|
57
62
|
return (0, amino_1.pubkeyToAddress)({
|
|
@@ -81,7 +86,7 @@ class TurboDataItemAbstractSigner {
|
|
|
81
86
|
return this.ownerToNativeAddress((0, base64_js_1.toB64Url)(await this.getPublicKey()), this.token);
|
|
82
87
|
}
|
|
83
88
|
/** Let the signer handle sending tx for better compat with cross chain libraries/web wallets */
|
|
84
|
-
async sendTransaction({ target, amount, gatewayUrl, }) {
|
|
89
|
+
async sendTransaction({ target, amount, gatewayUrl, turboCreditDestinationAddress, }) {
|
|
85
90
|
if (this.walletAdapter) {
|
|
86
91
|
if ((0, types_js_1.isSolanaWalletAdapter)(this.walletAdapter)) {
|
|
87
92
|
const connection = new web3_js_1.Connection(gatewayUrl, 'confirmed');
|
|
@@ -95,6 +100,14 @@ class TurboDataItemAbstractSigner {
|
|
|
95
100
|
toPubkey: new web3_js_1.PublicKey(target),
|
|
96
101
|
lamports: +new bignumber_js_1.BigNumber(amount),
|
|
97
102
|
}));
|
|
103
|
+
if (turboCreditDestinationAddress !== undefined) {
|
|
104
|
+
tx.add(new web3_js_1.TransactionInstruction({
|
|
105
|
+
programId: new web3_js_1.PublicKey(solana_js_1.memoProgramId),
|
|
106
|
+
keys: [],
|
|
107
|
+
data: Buffer.from('turboCreditDestinationAddress=' +
|
|
108
|
+
turboCreditDestinationAddress),
|
|
109
|
+
}));
|
|
110
|
+
}
|
|
98
111
|
const signedTx = await this.walletAdapter.signTransaction(tx);
|
|
99
112
|
const id = await connection.sendRawTransaction(signedTx.serialize());
|
|
100
113
|
return id;
|
|
@@ -109,6 +122,7 @@ class TurboDataItemAbstractSigner {
|
|
|
109
122
|
const { hash } = await signer.sendTransaction({
|
|
110
123
|
to: target,
|
|
111
124
|
value: (0, ethers_1.parseEther)(amount.toFixed(18)),
|
|
125
|
+
data: (0, ethereum_js_1.ethDataFromTurboCreditDestinationAddress)(turboCreditDestinationAddress),
|
|
112
126
|
});
|
|
113
127
|
return hash;
|
|
114
128
|
}
|
|
@@ -121,6 +135,7 @@ class TurboDataItemAbstractSigner {
|
|
|
121
135
|
const tx = await ethWalletAndProvider.sendTransaction({
|
|
122
136
|
to: target,
|
|
123
137
|
value: (0, ethers_1.parseEther)(amount.toFixed(18)),
|
|
138
|
+
data: (0, ethereum_js_1.ethDataFromTurboCreditDestinationAddress)(turboCreditDestinationAddress),
|
|
124
139
|
});
|
|
125
140
|
this.logger.debug('Sent transaction', { tx });
|
|
126
141
|
return tx.hash;
|
|
@@ -35,34 +35,42 @@ class ARIOToken {
|
|
|
35
35
|
this.pollingOptions = pollingOptions;
|
|
36
36
|
this.logger = logger;
|
|
37
37
|
}
|
|
38
|
-
async createAndSubmitTx({ target, signer: { signer }, tokenAmount, }) {
|
|
38
|
+
async createAndSubmitTx({ target, signer: { signer }, tokenAmount, turboCreditDestinationAddress, }) {
|
|
39
|
+
const tags = [
|
|
40
|
+
{
|
|
41
|
+
name: 'Action',
|
|
42
|
+
value: 'Transfer',
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
name: 'Recipient',
|
|
46
|
+
value: target,
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
name: 'Quantity',
|
|
50
|
+
value: tokenAmount.toString(),
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
name: 'Turbo-SDK',
|
|
54
|
+
value: version_js_1.version,
|
|
55
|
+
},
|
|
56
|
+
];
|
|
57
|
+
if (turboCreditDestinationAddress !== undefined) {
|
|
58
|
+
tags.push({
|
|
59
|
+
name: 'Turbo-Credit-Destination-Address',
|
|
60
|
+
value: turboCreditDestinationAddress,
|
|
61
|
+
});
|
|
62
|
+
}
|
|
39
63
|
const txId = await this.ao.message({
|
|
40
64
|
signer: createAoSigner(signer),
|
|
41
65
|
process: this.processId,
|
|
42
|
-
tags
|
|
43
|
-
{
|
|
44
|
-
name: 'Action',
|
|
45
|
-
value: 'Transfer',
|
|
46
|
-
},
|
|
47
|
-
{
|
|
48
|
-
name: 'Recipient',
|
|
49
|
-
value: target,
|
|
50
|
-
},
|
|
51
|
-
{
|
|
52
|
-
name: 'Quantity',
|
|
53
|
-
value: tokenAmount.toString(),
|
|
54
|
-
},
|
|
55
|
-
{
|
|
56
|
-
name: 'Turbo-SDK',
|
|
57
|
-
value: version_js_1.version,
|
|
58
|
-
},
|
|
59
|
-
],
|
|
66
|
+
tags,
|
|
60
67
|
});
|
|
61
68
|
this.logger.debug('Submitted Transfer message to ARIO process...', {
|
|
62
69
|
id: txId,
|
|
63
70
|
target,
|
|
64
71
|
tokenAmount,
|
|
65
72
|
processId: this.processId,
|
|
73
|
+
tags,
|
|
66
74
|
});
|
|
67
75
|
return { id: txId, target, reward: '0' };
|
|
68
76
|
}
|
|
@@ -46,7 +46,7 @@ class ArweaveToken {
|
|
|
46
46
|
this.mintU = mintU;
|
|
47
47
|
this.pollingOptions = pollingOptions;
|
|
48
48
|
}
|
|
49
|
-
async createAndSubmitTx({ feeMultiplier, target, tokenAmount, signer, }) {
|
|
49
|
+
async createAndSubmitTx({ feeMultiplier, target, tokenAmount, signer, turboCreditDestinationAddress, }) {
|
|
50
50
|
const tx = await this.arweave.createTransaction({
|
|
51
51
|
target,
|
|
52
52
|
quantity: tokenAmount.toString(),
|
|
@@ -63,6 +63,9 @@ class ArweaveToken {
|
|
|
63
63
|
tx.addTag('Contract', 'KTzTXT_ANmF84fWEKHzWURD1LWd9QaFR9yfYUwH2Lxw'); // cspell:enable
|
|
64
64
|
tx.addTag('Input', JSON.stringify({ function: 'mint' }));
|
|
65
65
|
}
|
|
66
|
+
if (turboCreditDestinationAddress !== undefined) {
|
|
67
|
+
tx.addTag('Turbo-Credit-Destination-Address', turboCreditDestinationAddress);
|
|
68
|
+
}
|
|
66
69
|
const publicKeyB64Url = (0, base64_js_1.toB64Url)(await signer.getPublicKey());
|
|
67
70
|
tx.setOwner(publicKeyB64Url);
|
|
68
71
|
const dataToSign = await tx.getSignatureData();
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.BaseEthToken = void 0;
|
|
3
|
+
exports.BaseEthToken = exports.defaultBaseNetworkPollingOptions = void 0;
|
|
4
4
|
const common_js_1 = require("../../utils/common.js");
|
|
5
5
|
const ethereum_js_1 = require("./ethereum.js");
|
|
6
|
+
exports.defaultBaseNetworkPollingOptions = {
|
|
7
|
+
initialBackoffMs: 2_500,
|
|
8
|
+
maxAttempts: 10,
|
|
9
|
+
pollingIntervalMs: 750,
|
|
10
|
+
};
|
|
6
11
|
class BaseEthToken extends ethereum_js_1.EthereumToken {
|
|
7
|
-
constructor({ logger, gatewayUrl = common_js_1.defaultProdGatewayUrls['base-eth'], pollingOptions = {
|
|
8
|
-
initialBackoffMs: 2_500,
|
|
9
|
-
maxAttempts: 10,
|
|
10
|
-
pollingIntervalMs: 2_500,
|
|
11
|
-
}, } = {}) {
|
|
12
|
+
constructor({ logger, gatewayUrl = common_js_1.defaultProdGatewayUrls['base-eth'], pollingOptions = exports.defaultBaseNetworkPollingOptions, } = {}) {
|
|
12
13
|
super({
|
|
13
14
|
logger,
|
|
14
15
|
gatewayUrl,
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ERC20Token = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Copyright (C) 2022-2024 Permanent Data Solutions, Inc.
|
|
6
|
+
*
|
|
7
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
8
|
+
* you may not use this file except in compliance with the License.
|
|
9
|
+
* You may obtain a copy of the License at
|
|
10
|
+
*
|
|
11
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
12
|
+
*
|
|
13
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
14
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
15
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
16
|
+
* See the License for the specific language governing permissions and
|
|
17
|
+
* limitations under the License.
|
|
18
|
+
*/
|
|
19
|
+
const arbundles_1 = require("@dha-team/arbundles");
|
|
20
|
+
const ethers_1 = require("ethers");
|
|
21
|
+
const types_js_1 = require("../../types.js");
|
|
22
|
+
const common_js_1 = require("../../utils/common.js");
|
|
23
|
+
const logger_js_1 = require("../logger.js");
|
|
24
|
+
const ethereum_js_1 = require("./ethereum.js");
|
|
25
|
+
class ERC20Token extends ethereum_js_1.EthereumToken {
|
|
26
|
+
constructor({ tokenContractAddress, logger = logger_js_1.TurboWinstonLogger.default, gatewayUrl = common_js_1.defaultProdGatewayUrls.ethereum, pollingOptions, }) {
|
|
27
|
+
super({ logger, gatewayUrl, pollingOptions });
|
|
28
|
+
this.tokenContract = new ethers_1.ethers.Contract(tokenContractAddress, [
|
|
29
|
+
'function decimals() view returns (uint8)',
|
|
30
|
+
'function balanceOf(address) view returns (uint256)',
|
|
31
|
+
'function transfer(address to, uint256 value) returns (bool)',
|
|
32
|
+
], this.rpcProvider);
|
|
33
|
+
}
|
|
34
|
+
async createAndSubmitTx({ target, tokenAmount, signer, turboCreditDestinationAddress, }) {
|
|
35
|
+
try {
|
|
36
|
+
let connected;
|
|
37
|
+
let walletOrSigner;
|
|
38
|
+
if (signer.signer instanceof arbundles_1.EthereumSigner) {
|
|
39
|
+
const provider = new ethers_1.JsonRpcProvider(this.gatewayUrl);
|
|
40
|
+
// 🧩 CLI / Node path
|
|
41
|
+
const keyHex = Buffer.from(signer.signer.key).toString('hex');
|
|
42
|
+
walletOrSigner = new ethers_1.Wallet(keyHex, provider);
|
|
43
|
+
connected = this.tokenContract.connect(walletOrSigner);
|
|
44
|
+
}
|
|
45
|
+
else if (signer.walletAdapter !== undefined &&
|
|
46
|
+
(0, types_js_1.isEthereumWalletAdapter)(signer.walletAdapter)) {
|
|
47
|
+
walletOrSigner = signer.walletAdapter.getSigner();
|
|
48
|
+
connected = this.tokenContract.connect(walletOrSigner);
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
throw new Error('Unsupported signer -- must be EthereumSigner or have a walletAdapter implementing getSigner');
|
|
52
|
+
}
|
|
53
|
+
// Encode transfer data
|
|
54
|
+
const baseTransferData = connected.interface.encodeFunctionData('transfer', [target, tokenAmount.toString()]);
|
|
55
|
+
let finalData = baseTransferData;
|
|
56
|
+
// Append optional memo data with turbo credit destination address
|
|
57
|
+
const memoData = (0, ethereum_js_1.ethDataFromTurboCreditDestinationAddress)(turboCreditDestinationAddress);
|
|
58
|
+
if (memoData !== undefined) {
|
|
59
|
+
// remove the "0x" prefix and append
|
|
60
|
+
finalData += memoData.slice(2);
|
|
61
|
+
}
|
|
62
|
+
const txRequest = {
|
|
63
|
+
to: await connected.getAddress(),
|
|
64
|
+
data: finalData,
|
|
65
|
+
};
|
|
66
|
+
this.logger.debug('Submitting ERC20 transfer', {
|
|
67
|
+
target,
|
|
68
|
+
tokenAmount: tokenAmount.toString(),
|
|
69
|
+
rpcEndpoint: this.gatewayUrl,
|
|
70
|
+
txRequest,
|
|
71
|
+
});
|
|
72
|
+
const tx = await walletOrSigner.sendTransaction(txRequest);
|
|
73
|
+
this.logger.debug('ERC20 transfer submitted', {
|
|
74
|
+
txHash: tx.hash,
|
|
75
|
+
target,
|
|
76
|
+
tx,
|
|
77
|
+
});
|
|
78
|
+
return { id: tx.hash, target };
|
|
79
|
+
}
|
|
80
|
+
catch (e) {
|
|
81
|
+
this.logger.error('Error creating/submitting ERC20 tx', {
|
|
82
|
+
error: e instanceof Error ? e.message : e,
|
|
83
|
+
target,
|
|
84
|
+
tokenAmount,
|
|
85
|
+
rpcEndpoint: this.gatewayUrl,
|
|
86
|
+
});
|
|
87
|
+
throw e;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
exports.ERC20Token = ERC20Token;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.EthereumToken = exports.ETHToTokenAmount = exports.weiToTokenAmount = void 0;
|
|
3
|
+
exports.EthereumToken = exports.defaultEthereumPollingOptions = exports.ETHToTokenAmount = exports.weiToTokenAmount = void 0;
|
|
4
|
+
exports.ethDataFromTurboCreditDestinationAddress = ethDataFromTurboCreditDestinationAddress;
|
|
4
5
|
/**
|
|
5
6
|
* Copyright (C) 2022-2024 Permanent Data Solutions, Inc.
|
|
6
7
|
*
|
|
@@ -24,29 +25,42 @@ const weiToTokenAmount = (wei) => wei;
|
|
|
24
25
|
exports.weiToTokenAmount = weiToTokenAmount;
|
|
25
26
|
const ETHToTokenAmount = (eth) => new bignumber_js_1.BigNumber(eth).times(1e18).valueOf();
|
|
26
27
|
exports.ETHToTokenAmount = ETHToTokenAmount;
|
|
28
|
+
exports.defaultEthereumPollingOptions = {
|
|
29
|
+
initialBackoffMs: 25_000,
|
|
30
|
+
maxAttempts: 10,
|
|
31
|
+
pollingIntervalMs: 1_500,
|
|
32
|
+
};
|
|
27
33
|
class EthereumToken {
|
|
28
|
-
constructor({ logger = logger_js_1.TurboWinstonLogger.default, gatewayUrl = common_js_1.defaultProdGatewayUrls.ethereum, pollingOptions = {
|
|
29
|
-
maxAttempts: 10,
|
|
30
|
-
pollingIntervalMs: 4_000,
|
|
31
|
-
initialBackoffMs: 10_000,
|
|
32
|
-
}, } = {}) {
|
|
34
|
+
constructor({ logger = logger_js_1.TurboWinstonLogger.default, gatewayUrl = common_js_1.defaultProdGatewayUrls.ethereum, pollingOptions = exports.defaultEthereumPollingOptions, } = {}) {
|
|
33
35
|
this.logger = logger;
|
|
34
36
|
this.gatewayUrl = gatewayUrl;
|
|
35
37
|
this.pollingOptions = pollingOptions;
|
|
36
38
|
this.rpcProvider = new ethers_1.ethers.JsonRpcProvider(gatewayUrl);
|
|
37
39
|
}
|
|
38
|
-
async createAndSubmitTx({ target, tokenAmount, signer, }) {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
40
|
+
async createAndSubmitTx({ target, tokenAmount, signer, turboCreditDestinationAddress, }) {
|
|
41
|
+
try {
|
|
42
|
+
// convert wei to eth
|
|
43
|
+
const eth = tokenAmount.shiftedBy(-18);
|
|
44
|
+
const txId = await signer.sendTransaction({
|
|
45
|
+
target,
|
|
46
|
+
amount: eth,
|
|
47
|
+
gatewayUrl: this.gatewayUrl,
|
|
48
|
+
turboCreditDestinationAddress,
|
|
49
|
+
});
|
|
50
|
+
return {
|
|
51
|
+
id: txId,
|
|
52
|
+
target,
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
catch (e) {
|
|
56
|
+
this.logger.error('Error creating and submitting Ethereum tx', {
|
|
57
|
+
error: e instanceof Error ? e.message : e,
|
|
58
|
+
target,
|
|
59
|
+
tokenAmount,
|
|
60
|
+
rpcEndpoint: this.gatewayUrl,
|
|
61
|
+
});
|
|
62
|
+
throw e;
|
|
63
|
+
}
|
|
50
64
|
}
|
|
51
65
|
async getTxAvailability(txId) {
|
|
52
66
|
const tx = await this.rpcProvider.getTransaction(txId);
|
|
@@ -77,3 +91,9 @@ class EthereumToken {
|
|
|
77
91
|
}
|
|
78
92
|
}
|
|
79
93
|
exports.EthereumToken = EthereumToken;
|
|
94
|
+
function ethDataFromTurboCreditDestinationAddress(turboCreditDestinationAddress) {
|
|
95
|
+
if (turboCreditDestinationAddress !== undefined) {
|
|
96
|
+
return (0, ethers_1.hexlify)((0, ethers_1.toUtf8Bytes)('turboCreditDestinationAddress=' + turboCreditDestinationAddress));
|
|
97
|
+
}
|
|
98
|
+
return undefined;
|
|
99
|
+
}
|
|
@@ -24,6 +24,7 @@ const ethereum_js_1 = require("./ethereum.js");
|
|
|
24
24
|
const kyve_js_1 = require("./kyve.js");
|
|
25
25
|
const polygon_js_1 = require("./polygon.js");
|
|
26
26
|
const solana_js_1 = require("./solana.js");
|
|
27
|
+
const usdc_js_1 = require("./usdc.js");
|
|
27
28
|
exports.defaultTokenMap = {
|
|
28
29
|
arweave: (config) => new arweave_js_1.ArweaveToken(config),
|
|
29
30
|
ario: (config) => new ario_js_1.ARIOToken(config),
|
|
@@ -33,8 +34,12 @@ exports.defaultTokenMap = {
|
|
|
33
34
|
kyve: (config) => new kyve_js_1.KyveToken(config),
|
|
34
35
|
matic: (config) => new polygon_js_1.PolygonToken(config),
|
|
35
36
|
pol: (config) => new polygon_js_1.PolygonToken(config),
|
|
37
|
+
usdc: (config) => new usdc_js_1.USDCToken({ network: 'ethereum', ...config }),
|
|
38
|
+
'base-usdc': (config) => new usdc_js_1.USDCToken({ network: 'base', ...config }),
|
|
39
|
+
'polygon-usdc': (config) => new usdc_js_1.USDCToken({ network: 'polygon', ...config }),
|
|
36
40
|
};
|
|
37
41
|
const ethExponent = 18;
|
|
42
|
+
const usdcExponent = 6;
|
|
38
43
|
exports.exponentMap = {
|
|
39
44
|
arweave: 12,
|
|
40
45
|
ario: 6,
|
|
@@ -44,6 +49,9 @@ exports.exponentMap = {
|
|
|
44
49
|
kyve: 6,
|
|
45
50
|
matic: ethExponent,
|
|
46
51
|
pol: ethExponent,
|
|
52
|
+
usdc: usdcExponent,
|
|
53
|
+
'base-usdc': usdcExponent,
|
|
54
|
+
'polygon-usdc': usdcExponent,
|
|
47
55
|
};
|
|
48
56
|
exports.tokenToBaseMap = {
|
|
49
57
|
arweave: (a) => (0, arweave_js_1.ARToTokenAmount)(a),
|
|
@@ -54,6 +62,9 @@ exports.tokenToBaseMap = {
|
|
|
54
62
|
kyve: (a) => (0, kyve_js_1.KYVEToTokenAmount)(a),
|
|
55
63
|
matic: (a) => (0, polygon_js_1.POLToTokenAmount)(a),
|
|
56
64
|
pol: (a) => (0, polygon_js_1.POLToTokenAmount)(a),
|
|
65
|
+
usdc: (a) => (0, usdc_js_1.USDCToTokenAmount)(a),
|
|
66
|
+
'base-usdc': (a) => (0, usdc_js_1.USDCToTokenAmount)(a),
|
|
67
|
+
'polygon-usdc': (a) => (0, usdc_js_1.USDCToTokenAmount)(a),
|
|
57
68
|
};
|
|
58
69
|
function isTokenType(token) {
|
|
59
70
|
return types_js_1.tokenTypes.includes(token);
|
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.PolygonToken = exports.POLToTokenAmount = void 0;
|
|
3
|
+
exports.PolygonToken = exports.defaultPolygonPollingOptions = exports.POLToTokenAmount = void 0;
|
|
4
4
|
const common_js_1 = require("../../utils/common.js");
|
|
5
5
|
const logger_js_1 = require("../logger.js");
|
|
6
6
|
const ethereum_js_1 = require("./ethereum.js");
|
|
7
7
|
exports.POLToTokenAmount = ethereum_js_1.ETHToTokenAmount;
|
|
8
|
+
exports.defaultPolygonPollingOptions = {
|
|
9
|
+
maxAttempts: 10,
|
|
10
|
+
initialBackoffMs: 5_000,
|
|
11
|
+
pollingIntervalMs: 1_000,
|
|
12
|
+
};
|
|
8
13
|
class PolygonToken extends ethereum_js_1.EthereumToken {
|
|
9
|
-
constructor({ logger = logger_js_1.TurboWinstonLogger.default, gatewayUrl = common_js_1.defaultProdGatewayUrls.pol, pollingOptions = {
|
|
10
|
-
maxAttempts: 10,
|
|
11
|
-
pollingIntervalMs: 4_000,
|
|
12
|
-
initialBackoffMs: 5_000,
|
|
13
|
-
}, } = {}) {
|
|
14
|
+
constructor({ logger = logger_js_1.TurboWinstonLogger.default, gatewayUrl = common_js_1.defaultProdGatewayUrls.pol, pollingOptions = exports.defaultPolygonPollingOptions, } = {}) {
|
|
14
15
|
super({ logger, gatewayUrl, pollingOptions });
|
|
15
16
|
}
|
|
16
17
|
}
|
|
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.SolanaToken = exports.SOLToTokenAmount = exports.lamportToTokenAmount = void 0;
|
|
6
|
+
exports.SolanaToken = exports.memoProgramId = exports.SOLToTokenAmount = exports.lamportToTokenAmount = void 0;
|
|
7
7
|
/**
|
|
8
8
|
* Copyright (C) 2022-2024 Permanent Data Solutions, Inc.
|
|
9
9
|
*
|
|
@@ -30,6 +30,7 @@ const lamportToTokenAmount = (winston) => winston;
|
|
|
30
30
|
exports.lamportToTokenAmount = lamportToTokenAmount;
|
|
31
31
|
const SOLToTokenAmount = (sol) => new bignumber_js_1.BigNumber(sol).times(1e9).valueOf();
|
|
32
32
|
exports.SOLToTokenAmount = SOLToTokenAmount;
|
|
33
|
+
exports.memoProgramId = 'MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr';
|
|
33
34
|
class SolanaToken {
|
|
34
35
|
constructor({ logger = logger_js_1.TurboWinstonLogger.default, gatewayUrl = common_js_1.defaultProdGatewayUrls.solana, pollingOptions = {
|
|
35
36
|
maxAttempts: 10,
|
|
@@ -41,12 +42,13 @@ class SolanaToken {
|
|
|
41
42
|
this.connection = new web3_js_1.Connection(gatewayUrl, 'confirmed');
|
|
42
43
|
this.pollingOptions = pollingOptions;
|
|
43
44
|
}
|
|
44
|
-
async createAndSubmitTx({ target, tokenAmount, signer, }) {
|
|
45
|
+
async createAndSubmitTx({ target, tokenAmount, signer, turboCreditDestinationAddress, }) {
|
|
45
46
|
if (signer.signer instanceof arbundles_1.HexInjectedSolanaSigner) {
|
|
46
47
|
const id = await signer.sendTransaction({
|
|
47
48
|
amount: tokenAmount,
|
|
48
49
|
target,
|
|
49
50
|
gatewayUrl: this.gatewayUrl,
|
|
51
|
+
turboCreditDestinationAddress,
|
|
50
52
|
});
|
|
51
53
|
return { target, id };
|
|
52
54
|
}
|
|
@@ -60,6 +62,13 @@ class SolanaToken {
|
|
|
60
62
|
toPubkey: new web3_js_1.PublicKey(target),
|
|
61
63
|
lamports: +new bignumber_js_1.BigNumber(tokenAmount),
|
|
62
64
|
}));
|
|
65
|
+
if (turboCreditDestinationAddress !== undefined) {
|
|
66
|
+
tx.add(new web3_js_1.TransactionInstruction({
|
|
67
|
+
programId: new web3_js_1.PublicKey(exports.memoProgramId),
|
|
68
|
+
keys: [],
|
|
69
|
+
data: Buffer.from('turboCreditDestinationAddress=' + turboCreditDestinationAddress),
|
|
70
|
+
}));
|
|
71
|
+
}
|
|
63
72
|
const serializedTx = tx.serializeMessage();
|
|
64
73
|
const signature = await signer.signData(Uint8Array.from(serializedTx));
|
|
65
74
|
tx.addSignature(publicKey, Buffer.from(signature));
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.USDCToken = exports.USDCToTokenAmount = exports.mUSDCToTokenAmount = exports.usdcNetworks = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Copyright (C) 2022-2024 Permanent Data Solutions, Inc.
|
|
6
|
+
*
|
|
7
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
8
|
+
* you may not use this file except in compliance with the License.
|
|
9
|
+
* You may obtain a copy of the License at
|
|
10
|
+
*
|
|
11
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
12
|
+
*
|
|
13
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
14
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
15
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
16
|
+
* See the License for the specific language governing permissions and
|
|
17
|
+
* limitations under the License.
|
|
18
|
+
*/
|
|
19
|
+
const bignumber_js_1 = require("bignumber.js");
|
|
20
|
+
const common_js_1 = require("../../utils/common.js");
|
|
21
|
+
const baseEth_js_1 = require("./baseEth.js");
|
|
22
|
+
const erc20_js_1 = require("./erc20.js");
|
|
23
|
+
const ethereum_js_1 = require("./ethereum.js");
|
|
24
|
+
const polygon_js_1 = require("./polygon.js");
|
|
25
|
+
/**
|
|
26
|
+
* Known USDC contract addresses and default RPCs by network
|
|
27
|
+
*/
|
|
28
|
+
const usdcNetworks = (useDevnet = false) => ({
|
|
29
|
+
ethereum: {
|
|
30
|
+
tokenContractAddress: useDevnet
|
|
31
|
+
? ethSepoliaUsdcAddress
|
|
32
|
+
: ethMainnetUsdcAddress,
|
|
33
|
+
rpcEndpoint: useDevnet
|
|
34
|
+
? common_js_1.tokenToDevGatewayMap.ethereum
|
|
35
|
+
: common_js_1.defaultProdGatewayUrls.ethereum,
|
|
36
|
+
defaultPollingOptions: ethereum_js_1.defaultEthereumPollingOptions,
|
|
37
|
+
},
|
|
38
|
+
base: {
|
|
39
|
+
tokenContractAddress: useDevnet
|
|
40
|
+
? baseSepoliaUsdcAddress
|
|
41
|
+
: baseMainnetUsdcAddress,
|
|
42
|
+
rpcEndpoint: useDevnet
|
|
43
|
+
? common_js_1.tokenToDevGatewayMap['base-eth']
|
|
44
|
+
: common_js_1.defaultProdGatewayUrls['base-eth'],
|
|
45
|
+
defaultPollingOptions: baseEth_js_1.defaultBaseNetworkPollingOptions,
|
|
46
|
+
},
|
|
47
|
+
polygon: {
|
|
48
|
+
tokenContractAddress: useDevnet
|
|
49
|
+
? polygonAmoyUsdcAddress
|
|
50
|
+
: polygonMainnetUsdcAddress,
|
|
51
|
+
rpcEndpoint: useDevnet
|
|
52
|
+
? common_js_1.tokenToDevGatewayMap.pol
|
|
53
|
+
: common_js_1.defaultProdGatewayUrls.pol,
|
|
54
|
+
defaultPollingOptions: polygon_js_1.defaultPolygonPollingOptions,
|
|
55
|
+
},
|
|
56
|
+
});
|
|
57
|
+
exports.usdcNetworks = usdcNetworks;
|
|
58
|
+
const ethMainnetUsdcAddress = '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48';
|
|
59
|
+
const baseMainnetUsdcAddress = '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913';
|
|
60
|
+
const polygonMainnetUsdcAddress = '0x3c499c542cef5e3811e1192ce70d8cc03d5c3359';
|
|
61
|
+
const ethSepoliaUsdcAddress = '0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238';
|
|
62
|
+
const baseSepoliaUsdcAddress = '0x036CbD53842c5426634e7929541eC2318f3dCF7e';
|
|
63
|
+
const polygonAmoyUsdcAddress = '0x41e94eb019c0762f9bfcf9fb1e58725bfb0e7582';
|
|
64
|
+
const mUSDCToTokenAmount = (mUSDC) => mUSDC;
|
|
65
|
+
exports.mUSDCToTokenAmount = mUSDCToTokenAmount;
|
|
66
|
+
const USDCToTokenAmount = (usdc) => new bignumber_js_1.BigNumber(usdc).times(1e6).valueOf();
|
|
67
|
+
exports.USDCToTokenAmount = USDCToTokenAmount;
|
|
68
|
+
class USDCToken extends erc20_js_1.ERC20Token {
|
|
69
|
+
constructor({ network = 'ethereum', logger, gatewayUrl, tokenContractAddress, pollingOptions, useDevnet, } = {}) {
|
|
70
|
+
if (useDevnet === undefined) {
|
|
71
|
+
const keywords = ['sepolia', 'amoy'];
|
|
72
|
+
useDevnet = keywords.some((keyword) => (gatewayUrl ?? '').toLowerCase().includes(keyword));
|
|
73
|
+
}
|
|
74
|
+
const { tokenContractAddress: usdcContractAddress, rpcEndpoint, defaultPollingOptions, } = (0, exports.usdcNetworks)(useDevnet)[network];
|
|
75
|
+
super({
|
|
76
|
+
tokenContractAddress: tokenContractAddress ?? usdcContractAddress,
|
|
77
|
+
logger,
|
|
78
|
+
gatewayUrl: gatewayUrl ?? rpcEndpoint,
|
|
79
|
+
pollingOptions: pollingOptions ?? defaultPollingOptions,
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
exports.USDCToken = USDCToken;
|
package/lib/cjs/common/upload.js
CHANGED
|
@@ -94,7 +94,12 @@ exports.TurboUnauthenticatedUploadService = TurboUnauthenticatedUploadService;
|
|
|
94
94
|
class TurboAuthenticatedBaseUploadService extends TurboUnauthenticatedUploadService {
|
|
95
95
|
constructor({ url = exports.defaultUploadServiceURL, retryConfig, signer, logger, token, paymentService, }) {
|
|
96
96
|
super({ url, retryConfig, logger, token });
|
|
97
|
-
this.enabledOnDemandTokens = [
|
|
97
|
+
this.enabledOnDemandTokens = [
|
|
98
|
+
'ario',
|
|
99
|
+
'solana',
|
|
100
|
+
'base-eth',
|
|
101
|
+
'base-usdc',
|
|
102
|
+
];
|
|
98
103
|
this.signer = signer;
|
|
99
104
|
this.paymentService = paymentService;
|
|
100
105
|
}
|