@rozoai/checkout 0.1.20 → 0.1.22
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 -9
- package/docs/QUICKSTART.es.md +15 -6
- package/docs/QUICKSTART.ja.md +9 -3
- package/docs/QUICKSTART.md +14 -5
- package/docs/QUICKSTART.zh.md +6 -4
- package/docs/README.es.md +20 -4
- package/docs/README.ja.md +19 -4
- package/docs/README.zh.md +19 -4
- package/llms.txt +24 -8
- package/package.json +7 -2
- package/scripts/dist/cli.js +1294 -553
- package/scripts/dist/create-order.js +209 -22
- package/scripts/dist/quote.js +107 -5
- package/scripts/dist/receipt.js +84 -13
- package/scripts/dist/resume.js +103 -18
- package/scripts/dist/send-evm.js +31852 -211
- package/scripts/dist/send-sol.js +468 -248
- package/scripts/dist/status.js +87 -13
package/scripts/dist/cli.js
CHANGED
|
@@ -1562,7 +1562,7 @@ function assertSize(hexOrBytes, { size: size5 }) {
|
|
|
1562
1562
|
maxSize: size5
|
|
1563
1563
|
});
|
|
1564
1564
|
}
|
|
1565
|
-
function
|
|
1565
|
+
function hexToBigInt2(hex, opts = {}) {
|
|
1566
1566
|
const { signed } = opts;
|
|
1567
1567
|
if (opts.size)
|
|
1568
1568
|
assertSize(hex, { size: opts.size });
|
|
@@ -1588,7 +1588,7 @@ function hexToBool(hex_, opts = {}) {
|
|
|
1588
1588
|
throw new InvalidHexBooleanError(hex);
|
|
1589
1589
|
}
|
|
1590
1590
|
function hexToNumber(hex, opts = {}) {
|
|
1591
|
-
const value =
|
|
1591
|
+
const value = hexToBigInt2(hex, opts);
|
|
1592
1592
|
const number = Number(value);
|
|
1593
1593
|
if (!Number.isSafeInteger(number))
|
|
1594
1594
|
throw new IntegerOutOfRangeError({
|
|
@@ -3102,7 +3102,7 @@ function bytesToBigInt(bytes, opts = {}) {
|
|
|
3102
3102
|
if (typeof opts.size !== "undefined")
|
|
3103
3103
|
assertSize(bytes, { size: opts.size });
|
|
3104
3104
|
const hex = bytesToHex(bytes);
|
|
3105
|
-
return
|
|
3105
|
+
return hexToBigInt2(hex, opts);
|
|
3106
3106
|
}
|
|
3107
3107
|
function bytesToBool(bytes_, opts = {}) {
|
|
3108
3108
|
let bytes = bytes_;
|
|
@@ -32374,7 +32374,7 @@ var require_index_cjs = __commonJS({
|
|
|
32374
32374
|
return value._bn !== void 0;
|
|
32375
32375
|
}
|
|
32376
32376
|
var uniquePublicKeyCounter = 1;
|
|
32377
|
-
var
|
|
32377
|
+
var PublicKey4 = class _PublicKey2 extends Struct {
|
|
32378
32378
|
/**
|
|
32379
32379
|
* Create a new PublicKey object
|
|
32380
32380
|
* @param value ed25519 public key as buffer or base-58 encoded string
|
|
@@ -32536,9 +32536,9 @@ var require_index_cjs = __commonJS({
|
|
|
32536
32536
|
return isOnCurve(pubkey.toBytes());
|
|
32537
32537
|
}
|
|
32538
32538
|
};
|
|
32539
|
-
_PublicKey =
|
|
32540
|
-
|
|
32541
|
-
SOLANA_SCHEMA.set(
|
|
32539
|
+
_PublicKey = PublicKey4;
|
|
32540
|
+
PublicKey4.default = new _PublicKey("11111111111111111111111111111111");
|
|
32541
|
+
SOLANA_SCHEMA.set(PublicKey4, {
|
|
32542
32542
|
kind: "struct",
|
|
32543
32543
|
fields: [["_bn", "u256"]]
|
|
32544
32544
|
});
|
|
@@ -32570,7 +32570,7 @@ var require_index_cjs = __commonJS({
|
|
|
32570
32570
|
* The public key for this account
|
|
32571
32571
|
*/
|
|
32572
32572
|
get publicKey() {
|
|
32573
|
-
return new
|
|
32573
|
+
return new PublicKey4(this._publicKey);
|
|
32574
32574
|
}
|
|
32575
32575
|
/**
|
|
32576
32576
|
* The **unencrypted** secret key for this account. The first 32 bytes
|
|
@@ -32581,7 +32581,7 @@ var require_index_cjs = __commonJS({
|
|
|
32581
32581
|
return buffer2.Buffer.concat([this._secretKey, this._publicKey], 64);
|
|
32582
32582
|
}
|
|
32583
32583
|
};
|
|
32584
|
-
var BPF_LOADER_DEPRECATED_PROGRAM_ID = new
|
|
32584
|
+
var BPF_LOADER_DEPRECATED_PROGRAM_ID = new PublicKey4("BPFLoader1111111111111111111111111111111111");
|
|
32585
32585
|
var PACKET_DATA_SIZE = 1280 - 40 - 8;
|
|
32586
32586
|
var VERSION_PREFIX_MASK = 127;
|
|
32587
32587
|
var SIGNATURE_LENGTH_IN_BYTES = 64;
|
|
@@ -32812,7 +32812,7 @@ var require_index_cjs = __commonJS({
|
|
|
32812
32812
|
const [payerAddress] = writableSigners[0];
|
|
32813
32813
|
assert8(payerAddress === this.payer.toBase58(), "Expected first writable signer key to be the fee payer");
|
|
32814
32814
|
}
|
|
32815
|
-
const staticAccountKeys = [...writableSigners.map(([address]) => new
|
|
32815
|
+
const staticAccountKeys = [...writableSigners.map(([address]) => new PublicKey4(address)), ...readonlySigners.map(([address]) => new PublicKey4(address)), ...writableNonSigners.map(([address]) => new PublicKey4(address)), ...readonlyNonSigners.map(([address]) => new PublicKey4(address))];
|
|
32816
32816
|
return [header, staticAccountKeys];
|
|
32817
32817
|
}
|
|
32818
32818
|
extractTableLookup(lookupTable) {
|
|
@@ -32836,7 +32836,7 @@ var require_index_cjs = __commonJS({
|
|
|
32836
32836
|
const drainedKeys = new Array();
|
|
32837
32837
|
for (const [address, keyMeta] of this.keyMetaMap.entries()) {
|
|
32838
32838
|
if (keyMetaFilter(keyMeta)) {
|
|
32839
|
-
const key = new
|
|
32839
|
+
const key = new PublicKey4(address);
|
|
32840
32840
|
const lookupTableIndex = lookupTableEntries.findIndex((entry) => entry.equals(key));
|
|
32841
32841
|
if (lookupTableIndex >= 0) {
|
|
32842
32842
|
assert8(lookupTableIndex < 256, "Max lookup table index exceeded");
|
|
@@ -32871,7 +32871,7 @@ var require_index_cjs = __commonJS({
|
|
|
32871
32871
|
this.instructions = void 0;
|
|
32872
32872
|
this.indexToProgramIds = /* @__PURE__ */ new Map();
|
|
32873
32873
|
this.header = args.header;
|
|
32874
|
-
this.accountKeys = args.accountKeys.map((account) => new
|
|
32874
|
+
this.accountKeys = args.accountKeys.map((account) => new PublicKey4(account));
|
|
32875
32875
|
this.recentBlockhash = args.recentBlockhash;
|
|
32876
32876
|
this.instructions = args.instructions;
|
|
32877
32877
|
this.instructions.forEach((ix) => this.indexToProgramIds.set(ix.programIdIndex, this.accountKeys[ix.programIdIndex]));
|
|
@@ -32997,7 +32997,7 @@ var require_index_cjs = __commonJS({
|
|
|
32997
32997
|
let accountKeys = [];
|
|
32998
32998
|
for (let i = 0; i < accountCount; i++) {
|
|
32999
32999
|
const account = guardedSplice(byteArray, 0, PUBLIC_KEY_LENGTH);
|
|
33000
|
-
accountKeys.push(new
|
|
33000
|
+
accountKeys.push(new PublicKey4(buffer2.Buffer.from(account)));
|
|
33001
33001
|
}
|
|
33002
33002
|
const recentBlockhash = guardedSplice(byteArray, 0, PUBLIC_KEY_LENGTH);
|
|
33003
33003
|
const instructionCount = decodeLength(byteArray);
|
|
@@ -33221,7 +33221,7 @@ var require_index_cjs = __commonJS({
|
|
|
33221
33221
|
const staticAccountKeys = [];
|
|
33222
33222
|
const staticAccountKeysLength = decodeLength(byteArray);
|
|
33223
33223
|
for (let i = 0; i < staticAccountKeysLength; i++) {
|
|
33224
|
-
staticAccountKeys.push(new
|
|
33224
|
+
staticAccountKeys.push(new PublicKey4(guardedSplice(byteArray, 0, PUBLIC_KEY_LENGTH)));
|
|
33225
33225
|
}
|
|
33226
33226
|
const recentBlockhash = bs58__default.default.encode(guardedSplice(byteArray, 0, PUBLIC_KEY_LENGTH));
|
|
33227
33227
|
const instructionCount = decodeLength(byteArray);
|
|
@@ -33241,7 +33241,7 @@ var require_index_cjs = __commonJS({
|
|
|
33241
33241
|
const addressTableLookupsCount = decodeLength(byteArray);
|
|
33242
33242
|
const addressTableLookups = [];
|
|
33243
33243
|
for (let i = 0; i < addressTableLookupsCount; i++) {
|
|
33244
|
-
const accountKey = new
|
|
33244
|
+
const accountKey = new PublicKey4(guardedSplice(byteArray, 0, PUBLIC_KEY_LENGTH));
|
|
33245
33245
|
const writableIndexesLength = decodeLength(byteArray);
|
|
33246
33246
|
const writableIndexes = guardedSplice(byteArray, 0, writableIndexesLength);
|
|
33247
33247
|
const readonlyIndexesLength = decodeLength(byteArray);
|
|
@@ -33290,7 +33290,7 @@ var require_index_cjs = __commonJS({
|
|
|
33290
33290
|
return TransactionStatus2;
|
|
33291
33291
|
})({});
|
|
33292
33292
|
var DEFAULT_SIGNATURE = buffer2.Buffer.alloc(SIGNATURE_LENGTH_IN_BYTES).fill(0);
|
|
33293
|
-
var
|
|
33293
|
+
var TransactionInstruction4 = class {
|
|
33294
33294
|
constructor(opts) {
|
|
33295
33295
|
this.keys = void 0;
|
|
33296
33296
|
this.programId = void 0;
|
|
@@ -33320,7 +33320,7 @@ var require_index_cjs = __commonJS({
|
|
|
33320
33320
|
};
|
|
33321
33321
|
}
|
|
33322
33322
|
};
|
|
33323
|
-
var
|
|
33323
|
+
var Transaction3 = class _Transaction {
|
|
33324
33324
|
/**
|
|
33325
33325
|
* The first (payer) Transaction signature
|
|
33326
33326
|
*
|
|
@@ -33422,7 +33422,7 @@ var require_index_cjs = __commonJS({
|
|
|
33422
33422
|
} else if ("data" in item && "programId" in item && "keys" in item) {
|
|
33423
33423
|
this.instructions.push(item);
|
|
33424
33424
|
} else {
|
|
33425
|
-
this.instructions.push(new
|
|
33425
|
+
this.instructions.push(new TransactionInstruction4(item));
|
|
33426
33426
|
}
|
|
33427
33427
|
});
|
|
33428
33428
|
return this;
|
|
@@ -33481,7 +33481,7 @@ var require_index_cjs = __commonJS({
|
|
|
33481
33481
|
});
|
|
33482
33482
|
programIds.forEach((programId) => {
|
|
33483
33483
|
accountMetas.push({
|
|
33484
|
-
pubkey: new
|
|
33484
|
+
pubkey: new PublicKey4(programId),
|
|
33485
33485
|
isSigner: false,
|
|
33486
33486
|
isWritable: false
|
|
33487
33487
|
});
|
|
@@ -33915,7 +33915,7 @@ Missing signature for public key${sigErrors.missing.length === 1 ? "" : "(s)"} [
|
|
|
33915
33915
|
isWritable: message.isAccountWritable(account)
|
|
33916
33916
|
};
|
|
33917
33917
|
});
|
|
33918
|
-
transaction.instructions.push(new
|
|
33918
|
+
transaction.instructions.push(new TransactionInstruction4({
|
|
33919
33919
|
keys,
|
|
33920
33920
|
programId: message.accountKeys[instruction.programIdIndex],
|
|
33921
33921
|
data: bs58__default.default.decode(instruction.data)
|
|
@@ -33983,7 +33983,7 @@ Missing signature for public key${sigErrors.missing.length === 1 ? "" : "(s)"} [
|
|
|
33983
33983
|
if (programId === void 0) {
|
|
33984
33984
|
throw new Error(`Failed to find program id for program id index ${compiledIx.programIdIndex}`);
|
|
33985
33985
|
}
|
|
33986
|
-
instructions.push(new
|
|
33986
|
+
instructions.push(new TransactionInstruction4({
|
|
33987
33987
|
programId,
|
|
33988
33988
|
data: toBuffer(compiledIx.data),
|
|
33989
33989
|
keys
|
|
@@ -34074,15 +34074,15 @@ Missing signature for public key${sigErrors.missing.length === 1 ? "" : "(s)"} [
|
|
|
34074
34074
|
var DEFAULT_TICKS_PER_SLOT = 64;
|
|
34075
34075
|
var NUM_SLOTS_PER_SECOND = NUM_TICKS_PER_SECOND / DEFAULT_TICKS_PER_SLOT;
|
|
34076
34076
|
var MS_PER_SLOT = 1e3 / NUM_SLOTS_PER_SECOND;
|
|
34077
|
-
var SYSVAR_CLOCK_PUBKEY = new
|
|
34078
|
-
var SYSVAR_EPOCH_SCHEDULE_PUBKEY = new
|
|
34079
|
-
var SYSVAR_INSTRUCTIONS_PUBKEY = new
|
|
34080
|
-
var SYSVAR_RECENT_BLOCKHASHES_PUBKEY = new
|
|
34081
|
-
var SYSVAR_RENT_PUBKEY = new
|
|
34082
|
-
var SYSVAR_REWARDS_PUBKEY = new
|
|
34083
|
-
var SYSVAR_SLOT_HASHES_PUBKEY = new
|
|
34084
|
-
var SYSVAR_SLOT_HISTORY_PUBKEY = new
|
|
34085
|
-
var SYSVAR_STAKE_HISTORY_PUBKEY = new
|
|
34077
|
+
var SYSVAR_CLOCK_PUBKEY = new PublicKey4("SysvarC1ock11111111111111111111111111111111");
|
|
34078
|
+
var SYSVAR_EPOCH_SCHEDULE_PUBKEY = new PublicKey4("SysvarEpochSchedu1e111111111111111111111111");
|
|
34079
|
+
var SYSVAR_INSTRUCTIONS_PUBKEY = new PublicKey4("Sysvar1nstructions1111111111111111111111111");
|
|
34080
|
+
var SYSVAR_RECENT_BLOCKHASHES_PUBKEY = new PublicKey4("SysvarRecentB1ockHashes11111111111111111111");
|
|
34081
|
+
var SYSVAR_RENT_PUBKEY = new PublicKey4("SysvarRent111111111111111111111111111111111");
|
|
34082
|
+
var SYSVAR_REWARDS_PUBKEY = new PublicKey4("SysvarRewards111111111111111111111111111111");
|
|
34083
|
+
var SYSVAR_SLOT_HASHES_PUBKEY = new PublicKey4("SysvarS1otHashes111111111111111111111111111");
|
|
34084
|
+
var SYSVAR_SLOT_HISTORY_PUBKEY = new PublicKey4("SysvarS1otHistory11111111111111111111111111");
|
|
34085
|
+
var SYSVAR_STAKE_HISTORY_PUBKEY = new PublicKey4("SysvarStakeHistory1111111111111111111111111");
|
|
34086
34086
|
var SendTransactionError = class extends Error {
|
|
34087
34087
|
constructor({
|
|
34088
34088
|
action,
|
|
@@ -34273,8 +34273,8 @@ Message: ${transactionMessage}.
|
|
|
34273
34273
|
static fromAccountData(buffer3) {
|
|
34274
34274
|
const nonceAccount = NonceAccountLayout.decode(toBuffer(buffer3), 0);
|
|
34275
34275
|
return new _NonceAccount({
|
|
34276
|
-
authorizedPubkey: new
|
|
34277
|
-
nonce: new
|
|
34276
|
+
authorizedPubkey: new PublicKey4(nonceAccount.authorizedPubkey),
|
|
34277
|
+
nonce: new PublicKey4(nonceAccount.nonce).toString(),
|
|
34278
34278
|
feeCalculator: nonceAccount.feeCalculator
|
|
34279
34279
|
});
|
|
34280
34280
|
}
|
|
@@ -34336,7 +34336,7 @@ Message: ${transactionMessage}.
|
|
|
34336
34336
|
newAccountPubkey: instruction.keys[1].pubkey,
|
|
34337
34337
|
lamports,
|
|
34338
34338
|
space,
|
|
34339
|
-
programId: new
|
|
34339
|
+
programId: new PublicKey4(programId)
|
|
34340
34340
|
};
|
|
34341
34341
|
}
|
|
34342
34342
|
/**
|
|
@@ -34371,7 +34371,7 @@ Message: ${transactionMessage}.
|
|
|
34371
34371
|
toPubkey: instruction.keys[2].pubkey,
|
|
34372
34372
|
lamports,
|
|
34373
34373
|
seed,
|
|
34374
|
-
programId: new
|
|
34374
|
+
programId: new PublicKey4(programId)
|
|
34375
34375
|
};
|
|
34376
34376
|
}
|
|
34377
34377
|
/**
|
|
@@ -34402,10 +34402,10 @@ Message: ${transactionMessage}.
|
|
|
34402
34402
|
} = decodeData$1(SYSTEM_INSTRUCTION_LAYOUTS.AllocateWithSeed, instruction.data);
|
|
34403
34403
|
return {
|
|
34404
34404
|
accountPubkey: instruction.keys[0].pubkey,
|
|
34405
|
-
basePubkey: new
|
|
34405
|
+
basePubkey: new PublicKey4(base),
|
|
34406
34406
|
seed,
|
|
34407
34407
|
space,
|
|
34408
|
-
programId: new
|
|
34408
|
+
programId: new PublicKey4(programId)
|
|
34409
34409
|
};
|
|
34410
34410
|
}
|
|
34411
34411
|
/**
|
|
@@ -34419,7 +34419,7 @@ Message: ${transactionMessage}.
|
|
|
34419
34419
|
} = decodeData$1(SYSTEM_INSTRUCTION_LAYOUTS.Assign, instruction.data);
|
|
34420
34420
|
return {
|
|
34421
34421
|
accountPubkey: instruction.keys[0].pubkey,
|
|
34422
|
-
programId: new
|
|
34422
|
+
programId: new PublicKey4(programId)
|
|
34423
34423
|
};
|
|
34424
34424
|
}
|
|
34425
34425
|
/**
|
|
@@ -34435,9 +34435,9 @@ Message: ${transactionMessage}.
|
|
|
34435
34435
|
} = decodeData$1(SYSTEM_INSTRUCTION_LAYOUTS.AssignWithSeed, instruction.data);
|
|
34436
34436
|
return {
|
|
34437
34437
|
accountPubkey: instruction.keys[0].pubkey,
|
|
34438
|
-
basePubkey: new
|
|
34438
|
+
basePubkey: new PublicKey4(base),
|
|
34439
34439
|
seed,
|
|
34440
|
-
programId: new
|
|
34440
|
+
programId: new PublicKey4(programId)
|
|
34441
34441
|
};
|
|
34442
34442
|
}
|
|
34443
34443
|
/**
|
|
@@ -34456,11 +34456,11 @@ Message: ${transactionMessage}.
|
|
|
34456
34456
|
return {
|
|
34457
34457
|
fromPubkey: instruction.keys[0].pubkey,
|
|
34458
34458
|
newAccountPubkey: instruction.keys[1].pubkey,
|
|
34459
|
-
basePubkey: new
|
|
34459
|
+
basePubkey: new PublicKey4(base),
|
|
34460
34460
|
seed,
|
|
34461
34461
|
lamports,
|
|
34462
34462
|
space,
|
|
34463
|
-
programId: new
|
|
34463
|
+
programId: new PublicKey4(programId)
|
|
34464
34464
|
};
|
|
34465
34465
|
}
|
|
34466
34466
|
/**
|
|
@@ -34474,7 +34474,7 @@ Message: ${transactionMessage}.
|
|
|
34474
34474
|
} = decodeData$1(SYSTEM_INSTRUCTION_LAYOUTS.InitializeNonceAccount, instruction.data);
|
|
34475
34475
|
return {
|
|
34476
34476
|
noncePubkey: instruction.keys[0].pubkey,
|
|
34477
|
-
authorizedPubkey: new
|
|
34477
|
+
authorizedPubkey: new PublicKey4(authorized2)
|
|
34478
34478
|
};
|
|
34479
34479
|
}
|
|
34480
34480
|
/**
|
|
@@ -34517,14 +34517,14 @@ Message: ${transactionMessage}.
|
|
|
34517
34517
|
return {
|
|
34518
34518
|
noncePubkey: instruction.keys[0].pubkey,
|
|
34519
34519
|
authorizedPubkey: instruction.keys[1].pubkey,
|
|
34520
|
-
newAuthorizedPubkey: new
|
|
34520
|
+
newAuthorizedPubkey: new PublicKey4(authorized2)
|
|
34521
34521
|
};
|
|
34522
34522
|
}
|
|
34523
34523
|
/**
|
|
34524
34524
|
* @internal
|
|
34525
34525
|
*/
|
|
34526
34526
|
static checkProgramId(programId) {
|
|
34527
|
-
if (!programId.equals(
|
|
34527
|
+
if (!programId.equals(SystemProgram2.programId)) {
|
|
34528
34528
|
throw new Error("invalid instruction; programId is not SystemProgram");
|
|
34529
34529
|
}
|
|
34530
34530
|
}
|
|
@@ -34591,7 +34591,7 @@ Message: ${transactionMessage}.
|
|
|
34591
34591
|
layout: BufferLayout__namespace.struct([BufferLayout__namespace.u32("instruction")])
|
|
34592
34592
|
}
|
|
34593
34593
|
});
|
|
34594
|
-
var
|
|
34594
|
+
var SystemProgram2 = class _SystemProgram {
|
|
34595
34595
|
/**
|
|
34596
34596
|
* @internal
|
|
34597
34597
|
*/
|
|
@@ -34610,7 +34610,7 @@ Message: ${transactionMessage}.
|
|
|
34610
34610
|
space: params.space,
|
|
34611
34611
|
programId: toBuffer(params.programId.toBuffer())
|
|
34612
34612
|
});
|
|
34613
|
-
return new
|
|
34613
|
+
return new TransactionInstruction4({
|
|
34614
34614
|
keys: [{
|
|
34615
34615
|
pubkey: params.fromPubkey,
|
|
34616
34616
|
isSigner: true,
|
|
@@ -34665,7 +34665,7 @@ Message: ${transactionMessage}.
|
|
|
34665
34665
|
isWritable: true
|
|
34666
34666
|
}];
|
|
34667
34667
|
}
|
|
34668
|
-
return new
|
|
34668
|
+
return new TransactionInstruction4({
|
|
34669
34669
|
keys,
|
|
34670
34670
|
programId: this.programId,
|
|
34671
34671
|
data
|
|
@@ -34704,7 +34704,7 @@ Message: ${transactionMessage}.
|
|
|
34704
34704
|
isWritable: true
|
|
34705
34705
|
}];
|
|
34706
34706
|
}
|
|
34707
|
-
return new
|
|
34707
|
+
return new TransactionInstruction4({
|
|
34708
34708
|
keys,
|
|
34709
34709
|
programId: this.programId,
|
|
34710
34710
|
data
|
|
@@ -34739,7 +34739,7 @@ Message: ${transactionMessage}.
|
|
|
34739
34739
|
isWritable: false
|
|
34740
34740
|
});
|
|
34741
34741
|
}
|
|
34742
|
-
return new
|
|
34742
|
+
return new TransactionInstruction4({
|
|
34743
34743
|
keys,
|
|
34744
34744
|
programId: this.programId,
|
|
34745
34745
|
data
|
|
@@ -34749,7 +34749,7 @@ Message: ${transactionMessage}.
|
|
|
34749
34749
|
* Generate a transaction that creates a new Nonce account
|
|
34750
34750
|
*/
|
|
34751
34751
|
static createNonceAccount(params) {
|
|
34752
|
-
const transaction = new
|
|
34752
|
+
const transaction = new Transaction3();
|
|
34753
34753
|
if ("basePubkey" in params && "seed" in params) {
|
|
34754
34754
|
transaction.add(_SystemProgram.createAccountWithSeed({
|
|
34755
34755
|
fromPubkey: params.fromPubkey,
|
|
@@ -34801,7 +34801,7 @@ Message: ${transactionMessage}.
|
|
|
34801
34801
|
programId: this.programId,
|
|
34802
34802
|
data
|
|
34803
34803
|
};
|
|
34804
|
-
return new
|
|
34804
|
+
return new TransactionInstruction4(instructionData);
|
|
34805
34805
|
}
|
|
34806
34806
|
/**
|
|
34807
34807
|
* Generate an instruction to advance the nonce in a Nonce account
|
|
@@ -34826,7 +34826,7 @@ Message: ${transactionMessage}.
|
|
|
34826
34826
|
programId: this.programId,
|
|
34827
34827
|
data
|
|
34828
34828
|
};
|
|
34829
|
-
return new
|
|
34829
|
+
return new TransactionInstruction4(instructionData);
|
|
34830
34830
|
}
|
|
34831
34831
|
/**
|
|
34832
34832
|
* Generate a transaction instruction that withdraws lamports from a Nonce account
|
|
@@ -34836,7 +34836,7 @@ Message: ${transactionMessage}.
|
|
|
34836
34836
|
const data = encodeData3(type, {
|
|
34837
34837
|
lamports: params.lamports
|
|
34838
34838
|
});
|
|
34839
|
-
return new
|
|
34839
|
+
return new TransactionInstruction4({
|
|
34840
34840
|
keys: [{
|
|
34841
34841
|
pubkey: params.noncePubkey,
|
|
34842
34842
|
isSigner: false,
|
|
@@ -34871,7 +34871,7 @@ Message: ${transactionMessage}.
|
|
|
34871
34871
|
const data = encodeData3(type, {
|
|
34872
34872
|
authorized: toBuffer(params.newAuthorizedPubkey.toBuffer())
|
|
34873
34873
|
});
|
|
34874
|
-
return new
|
|
34874
|
+
return new TransactionInstruction4({
|
|
34875
34875
|
keys: [{
|
|
34876
34876
|
pubkey: params.noncePubkey,
|
|
34877
34877
|
isSigner: false,
|
|
@@ -34919,14 +34919,14 @@ Message: ${transactionMessage}.
|
|
|
34919
34919
|
isWritable: true
|
|
34920
34920
|
}];
|
|
34921
34921
|
}
|
|
34922
|
-
return new
|
|
34922
|
+
return new TransactionInstruction4({
|
|
34923
34923
|
keys,
|
|
34924
34924
|
programId: this.programId,
|
|
34925
34925
|
data
|
|
34926
34926
|
});
|
|
34927
34927
|
}
|
|
34928
34928
|
};
|
|
34929
|
-
|
|
34929
|
+
SystemProgram2.programId = new PublicKey4("11111111111111111111111111111111");
|
|
34930
34930
|
var CHUNK_SIZE = PACKET_DATA_SIZE - 300;
|
|
34931
34931
|
var Loader = class _Loader {
|
|
34932
34932
|
/**
|
|
@@ -34969,29 +34969,29 @@ Message: ${transactionMessage}.
|
|
|
34969
34969
|
return false;
|
|
34970
34970
|
}
|
|
34971
34971
|
if (programInfo.data.length !== data.length) {
|
|
34972
|
-
transaction = transaction || new
|
|
34973
|
-
transaction.add(
|
|
34972
|
+
transaction = transaction || new Transaction3();
|
|
34973
|
+
transaction.add(SystemProgram2.allocate({
|
|
34974
34974
|
accountPubkey: program.publicKey,
|
|
34975
34975
|
space: data.length
|
|
34976
34976
|
}));
|
|
34977
34977
|
}
|
|
34978
34978
|
if (!programInfo.owner.equals(programId)) {
|
|
34979
|
-
transaction = transaction || new
|
|
34980
|
-
transaction.add(
|
|
34979
|
+
transaction = transaction || new Transaction3();
|
|
34980
|
+
transaction.add(SystemProgram2.assign({
|
|
34981
34981
|
accountPubkey: program.publicKey,
|
|
34982
34982
|
programId
|
|
34983
34983
|
}));
|
|
34984
34984
|
}
|
|
34985
34985
|
if (programInfo.lamports < balanceNeeded) {
|
|
34986
|
-
transaction = transaction || new
|
|
34987
|
-
transaction.add(
|
|
34986
|
+
transaction = transaction || new Transaction3();
|
|
34987
|
+
transaction.add(SystemProgram2.transfer({
|
|
34988
34988
|
fromPubkey: payer.publicKey,
|
|
34989
34989
|
toPubkey: program.publicKey,
|
|
34990
34990
|
lamports: balanceNeeded - programInfo.lamports
|
|
34991
34991
|
}));
|
|
34992
34992
|
}
|
|
34993
34993
|
} else {
|
|
34994
|
-
transaction = new
|
|
34994
|
+
transaction = new Transaction3().add(SystemProgram2.createAccount({
|
|
34995
34995
|
fromPubkey: payer.publicKey,
|
|
34996
34996
|
newAccountPubkey: program.publicKey,
|
|
34997
34997
|
lamports: balanceNeeded > 0 ? balanceNeeded : 1,
|
|
@@ -35021,7 +35021,7 @@ Message: ${transactionMessage}.
|
|
|
35021
35021
|
bytesLength: 0,
|
|
35022
35022
|
bytesLengthPadding: 0
|
|
35023
35023
|
}, data2);
|
|
35024
|
-
const transaction = new
|
|
35024
|
+
const transaction = new Transaction3().add({
|
|
35025
35025
|
keys: [{
|
|
35026
35026
|
pubkey: program.publicKey,
|
|
35027
35027
|
isSigner: true,
|
|
@@ -35048,7 +35048,7 @@ Message: ${transactionMessage}.
|
|
|
35048
35048
|
instruction: 1
|
|
35049
35049
|
// Finalize instruction
|
|
35050
35050
|
}, data2);
|
|
35051
|
-
const transaction = new
|
|
35051
|
+
const transaction = new Transaction3().add({
|
|
35052
35052
|
keys: [{
|
|
35053
35053
|
pubkey: program.publicKey,
|
|
35054
35054
|
isSigner: true,
|
|
@@ -35093,7 +35093,7 @@ Message: ${transactionMessage}.
|
|
|
35093
35093
|
}
|
|
35094
35094
|
};
|
|
35095
35095
|
Loader.chunkSize = CHUNK_SIZE;
|
|
35096
|
-
var BPF_LOADER_PROGRAM_ID = new
|
|
35096
|
+
var BPF_LOADER_PROGRAM_ID = new PublicKey4("BPFLoader2111111111111111111111111111111111");
|
|
35097
35097
|
var BpfLoader = class {
|
|
35098
35098
|
/**
|
|
35099
35099
|
* Minimum number of signatures required to load a program not including
|
|
@@ -35889,8 +35889,8 @@ Message: ${transactionMessage}.
|
|
|
35889
35889
|
deactivationSlot: meta.deactivationSlot,
|
|
35890
35890
|
lastExtendedSlot: meta.lastExtendedSlot,
|
|
35891
35891
|
lastExtendedSlotStartIndex: meta.lastExtendedStartIndex,
|
|
35892
|
-
authority: meta.authority.length !== 0 ? new
|
|
35893
|
-
addresses: addresses.map((address) => new
|
|
35892
|
+
authority: meta.authority.length !== 0 ? new PublicKey4(meta.authority[0]) : void 0,
|
|
35893
|
+
addresses: addresses.map((address) => new PublicKey4(address))
|
|
35894
35894
|
};
|
|
35895
35895
|
}
|
|
35896
35896
|
};
|
|
@@ -35932,7 +35932,7 @@ Message: ${transactionMessage}.
|
|
|
35932
35932
|
);
|
|
35933
35933
|
return `${protocol}//${hostish}${websocketPort}${rest}`;
|
|
35934
35934
|
}
|
|
35935
|
-
var PublicKeyFromString = superstruct.coerce(superstruct.instance(
|
|
35935
|
+
var PublicKeyFromString = superstruct.coerce(superstruct.instance(PublicKey4), superstruct.string(), (value) => new PublicKey4(value));
|
|
35936
35936
|
var RawAccountDataResult = superstruct.tuple([superstruct.string(), superstruct.literal("base64")]);
|
|
35937
35937
|
var BufferFromRawAccountData = superstruct.coerce(superstruct.instance(buffer2.Buffer), RawAccountDataResult, (value) => buffer2.Buffer.from(value[0], "base64"));
|
|
35938
35938
|
var BLOCKHASH_CACHE_TIMEOUT_MS = 30 * 1e3;
|
|
@@ -36017,7 +36017,7 @@ Message: ${transactionMessage}.
|
|
|
36017
36017
|
if (version5 === 0) {
|
|
36018
36018
|
return new MessageV0({
|
|
36019
36019
|
header: response.header,
|
|
36020
|
-
staticAccountKeys: response.accountKeys.map((accountKey) => new
|
|
36020
|
+
staticAccountKeys: response.accountKeys.map((accountKey) => new PublicKey4(accountKey)),
|
|
36021
36021
|
recentBlockhash: response.recentBlockhash,
|
|
36022
36022
|
compiledInstructions: response.instructions.map((ix) => ({
|
|
36023
36023
|
programIdIndex: ix.programIdIndex,
|
|
@@ -38207,7 +38207,7 @@ Message: ${transactionMessage}.
|
|
|
38207
38207
|
}) => {
|
|
38208
38208
|
return {
|
|
38209
38209
|
meta,
|
|
38210
|
-
transaction:
|
|
38210
|
+
transaction: Transaction3.populate(transaction.message, transaction.signatures)
|
|
38211
38211
|
};
|
|
38212
38212
|
})
|
|
38213
38213
|
};
|
|
@@ -38282,7 +38282,7 @@ Message: ${transactionMessage}.
|
|
|
38282
38282
|
const signatures = result.transaction.signatures;
|
|
38283
38283
|
return {
|
|
38284
38284
|
...result,
|
|
38285
|
-
transaction:
|
|
38285
|
+
transaction: Transaction3.populate(message, signatures)
|
|
38286
38286
|
};
|
|
38287
38287
|
}
|
|
38288
38288
|
/**
|
|
@@ -38569,15 +38569,15 @@ Message: ${transactionMessage}.
|
|
|
38569
38569
|
return res2.result;
|
|
38570
38570
|
}
|
|
38571
38571
|
let transaction;
|
|
38572
|
-
if (transactionOrMessage instanceof
|
|
38572
|
+
if (transactionOrMessage instanceof Transaction3) {
|
|
38573
38573
|
let originalTx = transactionOrMessage;
|
|
38574
|
-
transaction = new
|
|
38574
|
+
transaction = new Transaction3();
|
|
38575
38575
|
transaction.feePayer = originalTx.feePayer;
|
|
38576
38576
|
transaction.instructions = transactionOrMessage.instructions;
|
|
38577
38577
|
transaction.nonceInfo = originalTx.nonceInfo;
|
|
38578
38578
|
transaction.signatures = originalTx.signatures;
|
|
38579
38579
|
} else {
|
|
38580
|
-
transaction =
|
|
38580
|
+
transaction = Transaction3.populate(transactionOrMessage);
|
|
38581
38581
|
transaction._message = transaction._json = void 0;
|
|
38582
38582
|
}
|
|
38583
38583
|
if (configOrSigners !== void 0 && !Array.isArray(configOrSigners)) {
|
|
@@ -39457,7 +39457,7 @@ Message: ${transactionMessage}.
|
|
|
39457
39457
|
* @returns {PublicKey} PublicKey
|
|
39458
39458
|
*/
|
|
39459
39459
|
get publicKey() {
|
|
39460
|
-
return new
|
|
39460
|
+
return new PublicKey4(this._keypair.publicKey);
|
|
39461
39461
|
}
|
|
39462
39462
|
/**
|
|
39463
39463
|
* The raw secret key for this keypair
|
|
@@ -39535,7 +39535,7 @@ Message: ${transactionMessage}.
|
|
|
39535
39535
|
lookupTable: instruction.keys[0].pubkey,
|
|
39536
39536
|
authority: instruction.keys[1].pubkey,
|
|
39537
39537
|
payer: instruction.keys.length > 2 ? instruction.keys[2].pubkey : void 0,
|
|
39538
|
-
addresses: addresses.map((buffer3) => new
|
|
39538
|
+
addresses: addresses.map((buffer3) => new PublicKey4(buffer3))
|
|
39539
39539
|
};
|
|
39540
39540
|
}
|
|
39541
39541
|
static decodeCloseLookupTable(instruction) {
|
|
@@ -39587,7 +39587,7 @@ Message: ${transactionMessage}.
|
|
|
39587
39587
|
constructor() {
|
|
39588
39588
|
}
|
|
39589
39589
|
static createLookupTable(params) {
|
|
39590
|
-
const [lookupTableAddress, bumpSeed] =
|
|
39590
|
+
const [lookupTableAddress, bumpSeed] = PublicKey4.findProgramAddressSync([params.authority.toBuffer(), codecsNumbers.getU64Encoder().encode(params.recentSlot)], this.programId);
|
|
39591
39591
|
const type = LOOKUP_TABLE_INSTRUCTION_LAYOUTS.CreateLookupTable;
|
|
39592
39592
|
const data = encodeData3(type, {
|
|
39593
39593
|
recentSlot: BigInt(params.recentSlot),
|
|
@@ -39606,11 +39606,11 @@ Message: ${transactionMessage}.
|
|
|
39606
39606
|
isSigner: true,
|
|
39607
39607
|
isWritable: true
|
|
39608
39608
|
}, {
|
|
39609
|
-
pubkey:
|
|
39609
|
+
pubkey: SystemProgram2.programId,
|
|
39610
39610
|
isSigner: false,
|
|
39611
39611
|
isWritable: false
|
|
39612
39612
|
}];
|
|
39613
|
-
return [new
|
|
39613
|
+
return [new TransactionInstruction4({
|
|
39614
39614
|
programId: this.programId,
|
|
39615
39615
|
keys,
|
|
39616
39616
|
data
|
|
@@ -39628,7 +39628,7 @@ Message: ${transactionMessage}.
|
|
|
39628
39628
|
isSigner: true,
|
|
39629
39629
|
isWritable: false
|
|
39630
39630
|
}];
|
|
39631
|
-
return new
|
|
39631
|
+
return new TransactionInstruction4({
|
|
39632
39632
|
programId: this.programId,
|
|
39633
39633
|
keys,
|
|
39634
39634
|
data
|
|
@@ -39654,12 +39654,12 @@ Message: ${transactionMessage}.
|
|
|
39654
39654
|
isSigner: true,
|
|
39655
39655
|
isWritable: true
|
|
39656
39656
|
}, {
|
|
39657
|
-
pubkey:
|
|
39657
|
+
pubkey: SystemProgram2.programId,
|
|
39658
39658
|
isSigner: false,
|
|
39659
39659
|
isWritable: false
|
|
39660
39660
|
});
|
|
39661
39661
|
}
|
|
39662
|
-
return new
|
|
39662
|
+
return new TransactionInstruction4({
|
|
39663
39663
|
programId: this.programId,
|
|
39664
39664
|
keys,
|
|
39665
39665
|
data
|
|
@@ -39677,7 +39677,7 @@ Message: ${transactionMessage}.
|
|
|
39677
39677
|
isSigner: true,
|
|
39678
39678
|
isWritable: false
|
|
39679
39679
|
}];
|
|
39680
|
-
return new
|
|
39680
|
+
return new TransactionInstruction4({
|
|
39681
39681
|
programId: this.programId,
|
|
39682
39682
|
keys,
|
|
39683
39683
|
data
|
|
@@ -39699,14 +39699,14 @@ Message: ${transactionMessage}.
|
|
|
39699
39699
|
isSigner: false,
|
|
39700
39700
|
isWritable: true
|
|
39701
39701
|
}];
|
|
39702
|
-
return new
|
|
39702
|
+
return new TransactionInstruction4({
|
|
39703
39703
|
programId: this.programId,
|
|
39704
39704
|
keys,
|
|
39705
39705
|
data
|
|
39706
39706
|
});
|
|
39707
39707
|
}
|
|
39708
39708
|
};
|
|
39709
|
-
AddressLookupTableProgram.programId = new
|
|
39709
|
+
AddressLookupTableProgram.programId = new PublicKey4("AddressLookupTab1e1111111111111111111111111");
|
|
39710
39710
|
var ComputeBudgetInstruction = class {
|
|
39711
39711
|
/**
|
|
39712
39712
|
* @internal
|
|
@@ -39824,7 +39824,7 @@ Message: ${transactionMessage}.
|
|
|
39824
39824
|
static requestUnits(params) {
|
|
39825
39825
|
const type = COMPUTE_BUDGET_INSTRUCTION_LAYOUTS.RequestUnits;
|
|
39826
39826
|
const data = encodeData3(type, params);
|
|
39827
|
-
return new
|
|
39827
|
+
return new TransactionInstruction4({
|
|
39828
39828
|
keys: [],
|
|
39829
39829
|
programId: this.programId,
|
|
39830
39830
|
data
|
|
@@ -39833,7 +39833,7 @@ Message: ${transactionMessage}.
|
|
|
39833
39833
|
static requestHeapFrame(params) {
|
|
39834
39834
|
const type = COMPUTE_BUDGET_INSTRUCTION_LAYOUTS.RequestHeapFrame;
|
|
39835
39835
|
const data = encodeData3(type, params);
|
|
39836
|
-
return new
|
|
39836
|
+
return new TransactionInstruction4({
|
|
39837
39837
|
keys: [],
|
|
39838
39838
|
programId: this.programId,
|
|
39839
39839
|
data
|
|
@@ -39842,7 +39842,7 @@ Message: ${transactionMessage}.
|
|
|
39842
39842
|
static setComputeUnitLimit(params) {
|
|
39843
39843
|
const type = COMPUTE_BUDGET_INSTRUCTION_LAYOUTS.SetComputeUnitLimit;
|
|
39844
39844
|
const data = encodeData3(type, params);
|
|
39845
|
-
return new
|
|
39845
|
+
return new TransactionInstruction4({
|
|
39846
39846
|
keys: [],
|
|
39847
39847
|
programId: this.programId,
|
|
39848
39848
|
data
|
|
@@ -39853,14 +39853,14 @@ Message: ${transactionMessage}.
|
|
|
39853
39853
|
const data = encodeData3(type, {
|
|
39854
39854
|
microLamports: BigInt(params.microLamports)
|
|
39855
39855
|
});
|
|
39856
|
-
return new
|
|
39856
|
+
return new TransactionInstruction4({
|
|
39857
39857
|
keys: [],
|
|
39858
39858
|
programId: this.programId,
|
|
39859
39859
|
data
|
|
39860
39860
|
});
|
|
39861
39861
|
}
|
|
39862
39862
|
};
|
|
39863
|
-
ComputeBudgetProgram.programId = new
|
|
39863
|
+
ComputeBudgetProgram.programId = new PublicKey4("ComputeBudget111111111111111111111111111111");
|
|
39864
39864
|
var PRIVATE_KEY_BYTES$1 = 64;
|
|
39865
39865
|
var PUBLIC_KEY_BYTES$1 = 32;
|
|
39866
39866
|
var SIGNATURE_BYTES = 64;
|
|
@@ -39908,7 +39908,7 @@ Message: ${transactionMessage}.
|
|
|
39908
39908
|
instructionData.fill(publicKey2, publicKeyOffset);
|
|
39909
39909
|
instructionData.fill(signature2, signatureOffset);
|
|
39910
39910
|
instructionData.fill(message, messageDataOffset);
|
|
39911
|
-
return new
|
|
39911
|
+
return new TransactionInstruction4({
|
|
39912
39912
|
keys: [],
|
|
39913
39913
|
programId: _Ed25519Program.programId,
|
|
39914
39914
|
data: instructionData
|
|
@@ -39940,7 +39940,7 @@ Message: ${transactionMessage}.
|
|
|
39940
39940
|
}
|
|
39941
39941
|
}
|
|
39942
39942
|
};
|
|
39943
|
-
Ed25519Program.programId = new
|
|
39943
|
+
Ed25519Program.programId = new PublicKey4("Ed25519SigVerify111111111111111111111111111");
|
|
39944
39944
|
var ecdsaSign = (msgHash, privKey) => {
|
|
39945
39945
|
const signature2 = secp256k13.secp256k1.sign(msgHash, privKey);
|
|
39946
39946
|
return [signature2.toCompactRawBytes(), signature2.recovery];
|
|
@@ -40036,7 +40036,7 @@ Message: ${transactionMessage}.
|
|
|
40036
40036
|
recoveryId
|
|
40037
40037
|
}, instructionData);
|
|
40038
40038
|
instructionData.fill(toBuffer(message), SECP256K1_INSTRUCTION_LAYOUT.span);
|
|
40039
|
-
return new
|
|
40039
|
+
return new TransactionInstruction4({
|
|
40040
40040
|
keys: [],
|
|
40041
40041
|
programId: _Secp256k1Program.programId,
|
|
40042
40042
|
data: instructionData
|
|
@@ -40074,9 +40074,9 @@ Message: ${transactionMessage}.
|
|
|
40074
40074
|
}
|
|
40075
40075
|
}
|
|
40076
40076
|
};
|
|
40077
|
-
Secp256k1Program.programId = new
|
|
40077
|
+
Secp256k1Program.programId = new PublicKey4("KeccakSecp256k11111111111111111111111111111");
|
|
40078
40078
|
var _Lockup;
|
|
40079
|
-
var STAKE_CONFIG_ID = new
|
|
40079
|
+
var STAKE_CONFIG_ID = new PublicKey4("StakeConfig11111111111111111111111111111111");
|
|
40080
40080
|
var Authorized = class {
|
|
40081
40081
|
/**
|
|
40082
40082
|
* Create a new Authorized object
|
|
@@ -40107,7 +40107,7 @@ Message: ${transactionMessage}.
|
|
|
40107
40107
|
*/
|
|
40108
40108
|
};
|
|
40109
40109
|
_Lockup = Lockup;
|
|
40110
|
-
Lockup.default = new _Lockup(0, 0,
|
|
40110
|
+
Lockup.default = new _Lockup(0, 0, PublicKey4.default);
|
|
40111
40111
|
var StakeInstruction = class {
|
|
40112
40112
|
/**
|
|
40113
40113
|
* @internal
|
|
@@ -40145,8 +40145,8 @@ Message: ${transactionMessage}.
|
|
|
40145
40145
|
} = decodeData$1(STAKE_INSTRUCTION_LAYOUTS.Initialize, instruction.data);
|
|
40146
40146
|
return {
|
|
40147
40147
|
stakePubkey: instruction.keys[0].pubkey,
|
|
40148
|
-
authorized: new Authorized(new
|
|
40149
|
-
lockup: new Lockup(lockup2.unixTimestamp, lockup2.epoch, new
|
|
40148
|
+
authorized: new Authorized(new PublicKey4(authorized2.staker), new PublicKey4(authorized2.withdrawer)),
|
|
40149
|
+
lockup: new Lockup(lockup2.unixTimestamp, lockup2.epoch, new PublicKey4(lockup2.custodian))
|
|
40150
40150
|
};
|
|
40151
40151
|
}
|
|
40152
40152
|
/**
|
|
@@ -40175,7 +40175,7 @@ Message: ${transactionMessage}.
|
|
|
40175
40175
|
const o = {
|
|
40176
40176
|
stakePubkey: instruction.keys[0].pubkey,
|
|
40177
40177
|
authorizedPubkey: instruction.keys[2].pubkey,
|
|
40178
|
-
newAuthorizedPubkey: new
|
|
40178
|
+
newAuthorizedPubkey: new PublicKey4(newAuthorized),
|
|
40179
40179
|
stakeAuthorizationType: {
|
|
40180
40180
|
index: stakeAuthorizationType
|
|
40181
40181
|
}
|
|
@@ -40201,8 +40201,8 @@ Message: ${transactionMessage}.
|
|
|
40201
40201
|
stakePubkey: instruction.keys[0].pubkey,
|
|
40202
40202
|
authorityBase: instruction.keys[1].pubkey,
|
|
40203
40203
|
authoritySeed,
|
|
40204
|
-
authorityOwner: new
|
|
40205
|
-
newAuthorizedPubkey: new
|
|
40204
|
+
authorityOwner: new PublicKey4(authorityOwner),
|
|
40205
|
+
newAuthorizedPubkey: new PublicKey4(newAuthorized),
|
|
40206
40206
|
stakeAuthorizationType: {
|
|
40207
40207
|
index: stakeAuthorizationType
|
|
40208
40208
|
}
|
|
@@ -40376,15 +40376,15 @@ Message: ${transactionMessage}.
|
|
|
40376
40376
|
programId: this.programId,
|
|
40377
40377
|
data
|
|
40378
40378
|
};
|
|
40379
|
-
return new
|
|
40379
|
+
return new TransactionInstruction4(instructionData);
|
|
40380
40380
|
}
|
|
40381
40381
|
/**
|
|
40382
40382
|
* Generate a Transaction that creates a new Stake account at
|
|
40383
40383
|
* an address generated with `from`, a seed, and the Stake programId
|
|
40384
40384
|
*/
|
|
40385
40385
|
static createAccountWithSeed(params) {
|
|
40386
|
-
const transaction = new
|
|
40387
|
-
transaction.add(
|
|
40386
|
+
const transaction = new Transaction3();
|
|
40387
|
+
transaction.add(SystemProgram2.createAccountWithSeed({
|
|
40388
40388
|
fromPubkey: params.fromPubkey,
|
|
40389
40389
|
newAccountPubkey: params.stakePubkey,
|
|
40390
40390
|
basePubkey: params.basePubkey,
|
|
@@ -40408,8 +40408,8 @@ Message: ${transactionMessage}.
|
|
|
40408
40408
|
* Generate a Transaction that creates a new Stake account
|
|
40409
40409
|
*/
|
|
40410
40410
|
static createAccount(params) {
|
|
40411
|
-
const transaction = new
|
|
40412
|
-
transaction.add(
|
|
40411
|
+
const transaction = new Transaction3();
|
|
40412
|
+
transaction.add(SystemProgram2.createAccount({
|
|
40413
40413
|
fromPubkey: params.fromPubkey,
|
|
40414
40414
|
newAccountPubkey: params.stakePubkey,
|
|
40415
40415
|
lamports: params.lamports,
|
|
@@ -40440,7 +40440,7 @@ Message: ${transactionMessage}.
|
|
|
40440
40440
|
} = params;
|
|
40441
40441
|
const type = STAKE_INSTRUCTION_LAYOUTS.Delegate;
|
|
40442
40442
|
const data = encodeData3(type);
|
|
40443
|
-
return new
|
|
40443
|
+
return new Transaction3().add({
|
|
40444
40444
|
keys: [{
|
|
40445
40445
|
pubkey: stakePubkey,
|
|
40446
40446
|
isSigner: false,
|
|
@@ -40507,7 +40507,7 @@ Message: ${transactionMessage}.
|
|
|
40507
40507
|
isWritable: false
|
|
40508
40508
|
});
|
|
40509
40509
|
}
|
|
40510
|
-
return new
|
|
40510
|
+
return new Transaction3().add({
|
|
40511
40511
|
keys,
|
|
40512
40512
|
programId: this.programId,
|
|
40513
40513
|
data
|
|
@@ -40554,7 +40554,7 @@ Message: ${transactionMessage}.
|
|
|
40554
40554
|
isWritable: false
|
|
40555
40555
|
});
|
|
40556
40556
|
}
|
|
40557
|
-
return new
|
|
40557
|
+
return new Transaction3().add({
|
|
40558
40558
|
keys,
|
|
40559
40559
|
programId: this.programId,
|
|
40560
40560
|
data
|
|
@@ -40574,7 +40574,7 @@ Message: ${transactionMessage}.
|
|
|
40574
40574
|
const data = encodeData3(type, {
|
|
40575
40575
|
lamports
|
|
40576
40576
|
});
|
|
40577
|
-
return new
|
|
40577
|
+
return new TransactionInstruction4({
|
|
40578
40578
|
keys: [{
|
|
40579
40579
|
pubkey: stakePubkey,
|
|
40580
40580
|
isSigner: false,
|
|
@@ -40596,8 +40596,8 @@ Message: ${transactionMessage}.
|
|
|
40596
40596
|
* Generate a Transaction that splits Stake tokens into another stake account
|
|
40597
40597
|
*/
|
|
40598
40598
|
static split(params, rentExemptReserve) {
|
|
40599
|
-
const transaction = new
|
|
40600
|
-
transaction.add(
|
|
40599
|
+
const transaction = new Transaction3();
|
|
40600
|
+
transaction.add(SystemProgram2.createAccount({
|
|
40601
40601
|
fromPubkey: params.authorizedPubkey,
|
|
40602
40602
|
newAccountPubkey: params.splitStakePubkey,
|
|
40603
40603
|
lamports: rentExemptReserve,
|
|
@@ -40619,8 +40619,8 @@ Message: ${transactionMessage}.
|
|
|
40619
40619
|
seed,
|
|
40620
40620
|
lamports
|
|
40621
40621
|
} = params;
|
|
40622
|
-
const transaction = new
|
|
40623
|
-
transaction.add(
|
|
40622
|
+
const transaction = new Transaction3();
|
|
40623
|
+
transaction.add(SystemProgram2.allocate({
|
|
40624
40624
|
accountPubkey: splitStakePubkey,
|
|
40625
40625
|
basePubkey,
|
|
40626
40626
|
seed,
|
|
@@ -40628,7 +40628,7 @@ Message: ${transactionMessage}.
|
|
|
40628
40628
|
programId: this.programId
|
|
40629
40629
|
}));
|
|
40630
40630
|
if (rentExemptReserve && rentExemptReserve > 0) {
|
|
40631
|
-
transaction.add(
|
|
40631
|
+
transaction.add(SystemProgram2.transfer({
|
|
40632
40632
|
fromPubkey: params.authorizedPubkey,
|
|
40633
40633
|
toPubkey: splitStakePubkey,
|
|
40634
40634
|
lamports: rentExemptReserve
|
|
@@ -40652,7 +40652,7 @@ Message: ${transactionMessage}.
|
|
|
40652
40652
|
} = params;
|
|
40653
40653
|
const type = STAKE_INSTRUCTION_LAYOUTS.Merge;
|
|
40654
40654
|
const data = encodeData3(type);
|
|
40655
|
-
return new
|
|
40655
|
+
return new Transaction3().add({
|
|
40656
40656
|
keys: [{
|
|
40657
40657
|
pubkey: stakePubkey,
|
|
40658
40658
|
isSigner: false,
|
|
@@ -40721,7 +40721,7 @@ Message: ${transactionMessage}.
|
|
|
40721
40721
|
isWritable: false
|
|
40722
40722
|
});
|
|
40723
40723
|
}
|
|
40724
|
-
return new
|
|
40724
|
+
return new Transaction3().add({
|
|
40725
40725
|
keys,
|
|
40726
40726
|
programId: this.programId,
|
|
40727
40727
|
data
|
|
@@ -40737,7 +40737,7 @@ Message: ${transactionMessage}.
|
|
|
40737
40737
|
} = params;
|
|
40738
40738
|
const type = STAKE_INSTRUCTION_LAYOUTS.Deactivate;
|
|
40739
40739
|
const data = encodeData3(type);
|
|
40740
|
-
return new
|
|
40740
|
+
return new Transaction3().add({
|
|
40741
40741
|
keys: [{
|
|
40742
40742
|
pubkey: stakePubkey,
|
|
40743
40743
|
isSigner: false,
|
|
@@ -40756,7 +40756,7 @@ Message: ${transactionMessage}.
|
|
|
40756
40756
|
});
|
|
40757
40757
|
}
|
|
40758
40758
|
};
|
|
40759
|
-
StakeProgram.programId = new
|
|
40759
|
+
StakeProgram.programId = new PublicKey4("Stake11111111111111111111111111111111111111");
|
|
40760
40760
|
StakeProgram.space = 200;
|
|
40761
40761
|
var VoteInit = class {
|
|
40762
40762
|
/** [0, 100] */
|
|
@@ -40808,7 +40808,7 @@ Message: ${transactionMessage}.
|
|
|
40808
40808
|
return {
|
|
40809
40809
|
votePubkey: instruction.keys[0].pubkey,
|
|
40810
40810
|
nodePubkey: instruction.keys[3].pubkey,
|
|
40811
|
-
voteInit: new VoteInit(new
|
|
40811
|
+
voteInit: new VoteInit(new PublicKey4(voteInit2.nodePubkey), new PublicKey4(voteInit2.authorizedVoter), new PublicKey4(voteInit2.authorizedWithdrawer), voteInit2.commission)
|
|
40812
40812
|
};
|
|
40813
40813
|
}
|
|
40814
40814
|
/**
|
|
@@ -40824,7 +40824,7 @@ Message: ${transactionMessage}.
|
|
|
40824
40824
|
return {
|
|
40825
40825
|
votePubkey: instruction.keys[0].pubkey,
|
|
40826
40826
|
authorizedPubkey: instruction.keys[2].pubkey,
|
|
40827
|
-
newAuthorizedPubkey: new
|
|
40827
|
+
newAuthorizedPubkey: new PublicKey4(newAuthorized),
|
|
40828
40828
|
voteAuthorizationType: {
|
|
40829
40829
|
index: voteAuthorizationType
|
|
40830
40830
|
}
|
|
@@ -40846,9 +40846,9 @@ Message: ${transactionMessage}.
|
|
|
40846
40846
|
} = decodeData$1(VOTE_INSTRUCTION_LAYOUTS.AuthorizeWithSeed, instruction.data);
|
|
40847
40847
|
return {
|
|
40848
40848
|
currentAuthorityDerivedKeyBasePubkey: instruction.keys[2].pubkey,
|
|
40849
|
-
currentAuthorityDerivedKeyOwnerPubkey: new
|
|
40849
|
+
currentAuthorityDerivedKeyOwnerPubkey: new PublicKey4(currentAuthorityDerivedKeyOwnerPubkey),
|
|
40850
40850
|
currentAuthorityDerivedKeySeed,
|
|
40851
|
-
newAuthorizedPubkey: new
|
|
40851
|
+
newAuthorizedPubkey: new PublicKey4(newAuthorized),
|
|
40852
40852
|
voteAuthorizationType: {
|
|
40853
40853
|
index: voteAuthorizationType
|
|
40854
40854
|
},
|
|
@@ -40966,14 +40966,14 @@ Message: ${transactionMessage}.
|
|
|
40966
40966
|
programId: this.programId,
|
|
40967
40967
|
data
|
|
40968
40968
|
};
|
|
40969
|
-
return new
|
|
40969
|
+
return new TransactionInstruction4(instructionData);
|
|
40970
40970
|
}
|
|
40971
40971
|
/**
|
|
40972
40972
|
* Generate a transaction that creates a new Vote account.
|
|
40973
40973
|
*/
|
|
40974
40974
|
static createAccount(params) {
|
|
40975
|
-
const transaction = new
|
|
40976
|
-
transaction.add(
|
|
40975
|
+
const transaction = new Transaction3();
|
|
40976
|
+
transaction.add(SystemProgram2.createAccount({
|
|
40977
40977
|
fromPubkey: params.fromPubkey,
|
|
40978
40978
|
newAccountPubkey: params.votePubkey,
|
|
40979
40979
|
lamports: params.lamports,
|
|
@@ -41014,7 +41014,7 @@ Message: ${transactionMessage}.
|
|
|
41014
41014
|
isSigner: true,
|
|
41015
41015
|
isWritable: false
|
|
41016
41016
|
}];
|
|
41017
|
-
return new
|
|
41017
|
+
return new Transaction3().add({
|
|
41018
41018
|
keys,
|
|
41019
41019
|
programId: this.programId,
|
|
41020
41020
|
data
|
|
@@ -41055,7 +41055,7 @@ Message: ${transactionMessage}.
|
|
|
41055
41055
|
isSigner: true,
|
|
41056
41056
|
isWritable: false
|
|
41057
41057
|
}];
|
|
41058
|
-
return new
|
|
41058
|
+
return new Transaction3().add({
|
|
41059
41059
|
keys,
|
|
41060
41060
|
programId: this.programId,
|
|
41061
41061
|
data
|
|
@@ -41088,7 +41088,7 @@ Message: ${transactionMessage}.
|
|
|
41088
41088
|
isSigner: true,
|
|
41089
41089
|
isWritable: false
|
|
41090
41090
|
}];
|
|
41091
|
-
return new
|
|
41091
|
+
return new Transaction3().add({
|
|
41092
41092
|
keys,
|
|
41093
41093
|
programId: this.programId,
|
|
41094
41094
|
data
|
|
@@ -41132,16 +41132,16 @@ Message: ${transactionMessage}.
|
|
|
41132
41132
|
isSigner: true,
|
|
41133
41133
|
isWritable: false
|
|
41134
41134
|
}];
|
|
41135
|
-
return new
|
|
41135
|
+
return new Transaction3().add({
|
|
41136
41136
|
keys,
|
|
41137
41137
|
programId: this.programId,
|
|
41138
41138
|
data
|
|
41139
41139
|
});
|
|
41140
41140
|
}
|
|
41141
41141
|
};
|
|
41142
|
-
VoteProgram.programId = new
|
|
41142
|
+
VoteProgram.programId = new PublicKey4("Vote111111111111111111111111111111111111111");
|
|
41143
41143
|
VoteProgram.space = 3762;
|
|
41144
|
-
var VALIDATOR_INFO_KEY = new
|
|
41144
|
+
var VALIDATOR_INFO_KEY = new PublicKey4("Va1idator1nfo111111111111111111111111111111");
|
|
41145
41145
|
var InfoString = superstruct.type({
|
|
41146
41146
|
name: superstruct.string(),
|
|
41147
41147
|
website: superstruct.optional(superstruct.string()),
|
|
@@ -41175,7 +41175,7 @@ Message: ${transactionMessage}.
|
|
|
41175
41175
|
if (configKeyCount !== 2) return null;
|
|
41176
41176
|
const configKeys = [];
|
|
41177
41177
|
for (let i = 0; i < 2; i++) {
|
|
41178
|
-
const publicKey2 = new
|
|
41178
|
+
const publicKey2 = new PublicKey4(guardedSplice(byteArray, 0, PUBLIC_KEY_LENGTH));
|
|
41179
41179
|
const isSigner = guardedShift(byteArray) === 1;
|
|
41180
41180
|
configKeys.push({
|
|
41181
41181
|
publicKey: publicKey2,
|
|
@@ -41193,7 +41193,7 @@ Message: ${transactionMessage}.
|
|
|
41193
41193
|
return null;
|
|
41194
41194
|
}
|
|
41195
41195
|
};
|
|
41196
|
-
var VOTE_PROGRAM_ID = new
|
|
41196
|
+
var VOTE_PROGRAM_ID = new PublicKey4("Vote111111111111111111111111111111111111111");
|
|
41197
41197
|
var VoteAccountLayout = BufferLayout__namespace.struct([
|
|
41198
41198
|
publicKey("nodePubkey"),
|
|
41199
41199
|
publicKey("authorizedWithdrawer"),
|
|
@@ -41250,8 +41250,8 @@ Message: ${transactionMessage}.
|
|
|
41250
41250
|
rootSlot = null;
|
|
41251
41251
|
}
|
|
41252
41252
|
return new _VoteAccount({
|
|
41253
|
-
nodePubkey: new
|
|
41254
|
-
authorizedWithdrawer: new
|
|
41253
|
+
nodePubkey: new PublicKey4(va.nodePubkey),
|
|
41254
|
+
authorizedWithdrawer: new PublicKey4(va.authorizedWithdrawer),
|
|
41255
41255
|
commission: va.commission,
|
|
41256
41256
|
votes: va.votes,
|
|
41257
41257
|
rootSlot,
|
|
@@ -41268,7 +41268,7 @@ Message: ${transactionMessage}.
|
|
|
41268
41268
|
}) {
|
|
41269
41269
|
return {
|
|
41270
41270
|
epoch,
|
|
41271
|
-
authorizedVoter: new
|
|
41271
|
+
authorizedVoter: new PublicKey4(authorizedVoter)
|
|
41272
41272
|
};
|
|
41273
41273
|
}
|
|
41274
41274
|
function parsePriorVoters({
|
|
@@ -41277,7 +41277,7 @@ Message: ${transactionMessage}.
|
|
|
41277
41277
|
targetEpoch
|
|
41278
41278
|
}) {
|
|
41279
41279
|
return {
|
|
41280
|
-
authorizedPubkey: new
|
|
41280
|
+
authorizedPubkey: new PublicKey4(authorizedPubkey),
|
|
41281
41281
|
epochOfLastAuthorizedSwitch,
|
|
41282
41282
|
targetEpoch
|
|
41283
41283
|
};
|
|
@@ -41379,7 +41379,7 @@ Message: ${transactionMessage}.
|
|
|
41379
41379
|
exports.NonceAccount = NonceAccount;
|
|
41380
41380
|
exports.PACKET_DATA_SIZE = PACKET_DATA_SIZE;
|
|
41381
41381
|
exports.PUBLIC_KEY_LENGTH = PUBLIC_KEY_LENGTH;
|
|
41382
|
-
exports.PublicKey =
|
|
41382
|
+
exports.PublicKey = PublicKey4;
|
|
41383
41383
|
exports.SIGNATURE_LENGTH_IN_BYTES = SIGNATURE_LENGTH_IN_BYTES;
|
|
41384
41384
|
exports.SOLANA_SCHEMA = SOLANA_SCHEMA;
|
|
41385
41385
|
exports.STAKE_CONFIG_ID = STAKE_CONFIG_ID;
|
|
@@ -41403,12 +41403,12 @@ Message: ${transactionMessage}.
|
|
|
41403
41403
|
exports.StakeProgram = StakeProgram;
|
|
41404
41404
|
exports.Struct = Struct;
|
|
41405
41405
|
exports.SystemInstruction = SystemInstruction;
|
|
41406
|
-
exports.SystemProgram =
|
|
41407
|
-
exports.Transaction =
|
|
41406
|
+
exports.SystemProgram = SystemProgram2;
|
|
41407
|
+
exports.Transaction = Transaction3;
|
|
41408
41408
|
exports.TransactionExpiredBlockheightExceededError = TransactionExpiredBlockheightExceededError;
|
|
41409
41409
|
exports.TransactionExpiredNonceInvalidError = TransactionExpiredNonceInvalidError;
|
|
41410
41410
|
exports.TransactionExpiredTimeoutError = TransactionExpiredTimeoutError;
|
|
41411
|
-
exports.TransactionInstruction =
|
|
41411
|
+
exports.TransactionInstruction = TransactionInstruction4;
|
|
41412
41412
|
exports.TransactionMessage = TransactionMessage;
|
|
41413
41413
|
exports.TransactionStatus = TransactionStatus;
|
|
41414
41414
|
exports.VALIDATOR_INFO_KEY = VALIDATOR_INFO_KEY;
|
|
@@ -41643,6 +41643,7 @@ var CHAIN_NAMES = {
|
|
|
41643
41643
|
56: "BNB Chain",
|
|
41644
41644
|
137: "Polygon",
|
|
41645
41645
|
8453: "Base",
|
|
41646
|
+
42161: "Arbitrum",
|
|
41646
41647
|
900: "Solana",
|
|
41647
41648
|
1500: "Stellar",
|
|
41648
41649
|
lightning: "Bitcoin Lightning"
|
|
@@ -41652,19 +41653,31 @@ var CHAIN_FAMILY = {
|
|
|
41652
41653
|
56: "evm",
|
|
41653
41654
|
137: "evm",
|
|
41654
41655
|
8453: "evm",
|
|
41656
|
+
42161: "evm",
|
|
41655
41657
|
900: "solana",
|
|
41656
41658
|
1500: "stellar",
|
|
41657
41659
|
lightning: "lightning"
|
|
41658
41660
|
};
|
|
41659
41661
|
var SUPPORTED_SOURCES = [
|
|
41660
|
-
{ chainId: "1", chain: "Ethereum", tokens: ["USDC", "USDT"] },
|
|
41661
|
-
{ chainId: "56", chain: "BNB Chain", tokens: ["USDC", "USDT"] },
|
|
41662
|
-
{ chainId: "137", chain: "Polygon", tokens: ["USDC", "USDT"] },
|
|
41663
|
-
{ chainId: "900", chain: "Solana", tokens: ["USDC", "USDT"] },
|
|
41664
|
-
{ chainId: "8453", chain: "Base", tokens: ["USDC"] },
|
|
41662
|
+
{ chainId: "1", chain: "Ethereum", tokens: ["USDC", "USDT", "ETH"] },
|
|
41663
|
+
{ chainId: "56", chain: "BNB Chain", tokens: ["USDC", "USDT", "BNB"] },
|
|
41664
|
+
{ chainId: "137", chain: "Polygon", tokens: ["USDC", "USDT", "POL"] },
|
|
41665
|
+
{ chainId: "900", chain: "Solana", tokens: ["USDC", "USDT", "SOL"] },
|
|
41666
|
+
{ chainId: "8453", chain: "Base", tokens: ["USDC", "ETH"] },
|
|
41667
|
+
{ chainId: "42161", chain: "Arbitrum", tokens: ["USDC", "USDT", "ETH"] },
|
|
41665
41668
|
{ chainId: "1500", chain: "Stellar", tokens: ["USDC"] },
|
|
41666
41669
|
{ chainId: "lightning", chain: "Bitcoin Lightning", tokens: ["BTC"] }
|
|
41667
41670
|
];
|
|
41671
|
+
var NATIVE_COINS = Object.freeze({
|
|
41672
|
+
"1:ETH": { chainId: "1", symbol: "ETH", decimals: 18 },
|
|
41673
|
+
"8453:ETH": { chainId: "8453", symbol: "ETH", decimals: 18 },
|
|
41674
|
+
"42161:ETH": { chainId: "42161", symbol: "ETH", decimals: 18 },
|
|
41675
|
+
"56:BNB": { chainId: "56", symbol: "BNB", decimals: 18 },
|
|
41676
|
+
"137:POL": { chainId: "137", symbol: "POL", decimals: 18 },
|
|
41677
|
+
"900:SOL": { chainId: "900", symbol: "SOL", decimals: 9 }
|
|
41678
|
+
});
|
|
41679
|
+
var NATIVE_MAX_USD = 2e3;
|
|
41680
|
+
var NATIVE_MIN_USD_FALLBACK = Object.freeze({ "1:ETH": 1 });
|
|
41668
41681
|
var DECIMALS = {
|
|
41669
41682
|
"1:USDC": 6,
|
|
41670
41683
|
"1:USDT": 6,
|
|
@@ -41674,10 +41687,20 @@ var DECIMALS = {
|
|
|
41674
41687
|
"137:USDC": 6,
|
|
41675
41688
|
"137:USDT": 6,
|
|
41676
41689
|
"8453:USDC": 6,
|
|
41690
|
+
// Arbitrum One: native USDC and USDT0 are both 6-decimals.
|
|
41691
|
+
"42161:USDC": 6,
|
|
41692
|
+
"42161:USDT": 6,
|
|
41677
41693
|
"900:USDC": 6,
|
|
41678
41694
|
"900:USDT": 6,
|
|
41679
41695
|
// Stellar classic assets carry 7 decimal places.
|
|
41680
|
-
"1500:USDC": 7
|
|
41696
|
+
"1500:USDC": 7,
|
|
41697
|
+
// Native coins: wei (18) on every EVM chain, lamports (9) on Solana.
|
|
41698
|
+
"1:ETH": 18,
|
|
41699
|
+
"8453:ETH": 18,
|
|
41700
|
+
"42161:ETH": 18,
|
|
41701
|
+
"56:BNB": 18,
|
|
41702
|
+
"137:POL": 18,
|
|
41703
|
+
"900:SOL": 9
|
|
41681
41704
|
};
|
|
41682
41705
|
var AmountError = class extends Error {
|
|
41683
41706
|
constructor(code, message) {
|
|
@@ -41779,6 +41802,74 @@ function isSupportedSource(chainId, tokenSymbol) {
|
|
|
41779
41802
|
const sym = String(tokenSymbol || "").trim().toUpperCase();
|
|
41780
41803
|
return SUPPORTED_SOURCES.some((s) => s.chainId === cid && s.tokens.includes(sym));
|
|
41781
41804
|
}
|
|
41805
|
+
function isNativeSource(chainId, tokenSymbol) {
|
|
41806
|
+
return Object.prototype.hasOwnProperty.call(NATIVE_COINS, decimalsKey(chainId, tokenSymbol));
|
|
41807
|
+
}
|
|
41808
|
+
var NATIVE_TOKEN_ADDRESSES = /* @__PURE__ */ new Set([
|
|
41809
|
+
"",
|
|
41810
|
+
"0x0000000000000000000000000000000000000000",
|
|
41811
|
+
"0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee",
|
|
41812
|
+
"native",
|
|
41813
|
+
"11111111111111111111111111111111"
|
|
41814
|
+
]);
|
|
41815
|
+
function isNativeTokenAddress(tokenAddress) {
|
|
41816
|
+
if (tokenAddress === null || tokenAddress === void 0) return true;
|
|
41817
|
+
return NATIVE_TOKEN_ADDRESSES.has(String(tokenAddress).trim().toLowerCase());
|
|
41818
|
+
}
|
|
41819
|
+
function nativeMinUsdFor(chainId, tokenSymbol, quoteNativeMinUsd) {
|
|
41820
|
+
const cid = String(chainId).trim();
|
|
41821
|
+
const sym = String(tokenSymbol || "").trim().toUpperCase();
|
|
41822
|
+
const fromQuote = quoteNativeMinUsd?.[cid]?.[sym];
|
|
41823
|
+
const n = Number(fromQuote);
|
|
41824
|
+
if (fromQuote !== void 0 && fromQuote !== null && Number.isFinite(n) && n > 0) return n;
|
|
41825
|
+
return NATIVE_MIN_USD_FALLBACK[`${cid}:${sym}`] ?? null;
|
|
41826
|
+
}
|
|
41827
|
+
function nativeOfferFor({ chainId, tokenSymbol, supportedSources, nativeMinUsd, callerPaysUsd }) {
|
|
41828
|
+
const cid = String(chainId).trim();
|
|
41829
|
+
const sym = String(tokenSymbol || "").trim().toUpperCase();
|
|
41830
|
+
const label = `${sym} on ${chainName(cid)}`;
|
|
41831
|
+
const minUsd = nativeMinUsdFor(cid, sym, nativeMinUsd);
|
|
41832
|
+
if (!isNativeSource(cid, sym)) {
|
|
41833
|
+
return { ok: false, code: "NOT_NATIVE", reason: `${label} is not a native coin.`, minUsd: null };
|
|
41834
|
+
}
|
|
41835
|
+
const list = supportedSources && typeof supportedSources === "object" ? supportedSources[cid] : null;
|
|
41836
|
+
if (!Array.isArray(list) || !list.map((t) => String(t).toUpperCase()).includes(sym)) {
|
|
41837
|
+
return {
|
|
41838
|
+
ok: false,
|
|
41839
|
+
code: "NATIVE_NOT_OFFERED",
|
|
41840
|
+
reason: `${label} is not offered for this invoice. Pay with USDC or USDT instead.`,
|
|
41841
|
+
minUsd
|
|
41842
|
+
};
|
|
41843
|
+
}
|
|
41844
|
+
const usd = Number(callerPaysUsd);
|
|
41845
|
+
if (!Number.isFinite(usd) || usd <= 0) {
|
|
41846
|
+
return {
|
|
41847
|
+
ok: false,
|
|
41848
|
+
code: "NATIVE_AMOUNT_UNKNOWN",
|
|
41849
|
+
reason: `The quote carries no USD amount, so ${label} cannot be checked against the native limits. Pay with USDC or USDT instead.`,
|
|
41850
|
+
minUsd
|
|
41851
|
+
};
|
|
41852
|
+
}
|
|
41853
|
+
{
|
|
41854
|
+
if (usd > NATIVE_MAX_USD) {
|
|
41855
|
+
return {
|
|
41856
|
+
ok: false,
|
|
41857
|
+
code: "NATIVE_AMOUNT_TOO_HIGH",
|
|
41858
|
+
reason: `Native coin orders are limited to $${NATIVE_MAX_USD} per invoice; this one is $${usd}. Pay with USDC or USDT instead.`,
|
|
41859
|
+
minUsd
|
|
41860
|
+
};
|
|
41861
|
+
}
|
|
41862
|
+
if (minUsd !== null && usd < minUsd) {
|
|
41863
|
+
return {
|
|
41864
|
+
ok: false,
|
|
41865
|
+
code: "NATIVE_AMOUNT_TOO_LOW",
|
|
41866
|
+
reason: `${label} needs an invoice of at least $${minUsd}; this one is $${usd}. Pay with another coin.`,
|
|
41867
|
+
minUsd
|
|
41868
|
+
};
|
|
41869
|
+
}
|
|
41870
|
+
}
|
|
41871
|
+
return { ok: true, code: null, reason: null, minUsd };
|
|
41872
|
+
}
|
|
41782
41873
|
|
|
41783
41874
|
// scripts/src/lib/utm.mjs
|
|
41784
41875
|
function normalizeUtmSource(value) {
|
|
@@ -41853,6 +41944,9 @@ var CHAIN_ALIASES = {
|
|
|
41853
41944
|
polygon: "137",
|
|
41854
41945
|
matic: "137",
|
|
41855
41946
|
base: "8453",
|
|
41947
|
+
arbitrum: "42161",
|
|
41948
|
+
arb: "42161",
|
|
41949
|
+
arbitrumone: "42161",
|
|
41856
41950
|
solana: "900",
|
|
41857
41951
|
sol: "900",
|
|
41858
41952
|
stellar: "1500",
|
|
@@ -41862,34 +41956,69 @@ var CHAIN_ALIASES = {
|
|
|
41862
41956
|
bitcoin: "lightning",
|
|
41863
41957
|
btc: "lightning"
|
|
41864
41958
|
};
|
|
41865
|
-
var
|
|
41866
|
-
|
|
41867
|
-
|
|
41868
|
-
|
|
41869
|
-
|
|
41870
|
-
|
|
41871
|
-
|
|
41872
|
-
|
|
41873
|
-
|
|
41874
|
-
|
|
41875
|
-
|
|
41876
|
-
|
|
41877
|
-
|
|
41878
|
-
|
|
41959
|
+
var PRESET_CHAIN = {
|
|
41960
|
+
"900": "solana",
|
|
41961
|
+
"56": "bnb",
|
|
41962
|
+
"1": "ethereum",
|
|
41963
|
+
"137": "polygon",
|
|
41964
|
+
"8453": "base",
|
|
41965
|
+
"42161": "arbitrum",
|
|
41966
|
+
"1500": "stellar",
|
|
41967
|
+
lightning: "lightning"
|
|
41968
|
+
};
|
|
41969
|
+
var PRESET_SHORTCUTS = Object.freeze({
|
|
41970
|
+
bnb: "bnb-bnb",
|
|
41971
|
+
sol: "sol-solana",
|
|
41972
|
+
pol: "pol-polygon"
|
|
41973
|
+
});
|
|
41974
|
+
var PICKER_ROWS = [
|
|
41975
|
+
{ group: "USDT", token: "USDT", chain: "Solana", chainId: "900" },
|
|
41976
|
+
{ group: "USDT", token: "USDT", chain: "BNB Chain", chainId: "56" },
|
|
41977
|
+
{ group: "USDT", token: "USDT", chain: "Ethereum", chainId: "1" },
|
|
41978
|
+
{ group: "USDT", token: "USDT", chain: "Polygon", chainId: "137" },
|
|
41979
|
+
{ group: "USDT", token: "USDT", chain: "Arbitrum", chainId: "42161" },
|
|
41980
|
+
{ group: "USDC", token: "USDC", chain: "Solana", chainId: "900" },
|
|
41981
|
+
{ group: "USDC", token: "USDC", chain: "BNB Chain", chainId: "56" },
|
|
41982
|
+
{ group: "USDC", token: "USDC", chain: "Ethereum", chainId: "1" },
|
|
41983
|
+
{ group: "USDC", token: "USDC", chain: "Polygon", chainId: "137" },
|
|
41984
|
+
{ group: "USDC", token: "USDC", chain: "Base", chainId: "8453" },
|
|
41985
|
+
{ group: "USDC", token: "USDC", chain: "Arbitrum", chainId: "42161" },
|
|
41986
|
+
{ group: "USDC", token: "USDC", chain: "Stellar", chainId: "1500" },
|
|
41987
|
+
{ group: "BTC", token: "BTC", chain: "Lightning", chainId: "lightning" },
|
|
41988
|
+
{ group: "Native coins", token: "ETH", chain: "Base", chainId: "8453" },
|
|
41989
|
+
{ group: "Native coins", token: "ETH", chain: "Ethereum", chainId: "1" },
|
|
41990
|
+
{ group: "Native coins", token: "ETH", chain: "Arbitrum", chainId: "42161" },
|
|
41991
|
+
{ group: "Native coins", token: "BNB", chain: "BNB Chain", chainId: "56" },
|
|
41992
|
+
{ group: "Native coins", token: "SOL", chain: "Solana", chainId: "900" },
|
|
41993
|
+
{ group: "Native coins", token: "POL", chain: "Polygon", chainId: "137" }
|
|
41994
|
+
].map((o) => ({
|
|
41879
41995
|
...o,
|
|
41880
41996
|
tokenSymbol: o.token,
|
|
41997
|
+
native: isNativeSource(o.chainId, o.token),
|
|
41998
|
+
// What a row says after its number. Native rows name the coin, since the
|
|
41999
|
+
// group heading does not.
|
|
42000
|
+
label: isNativeSource(o.chainId, o.token) ? `${o.token} on ${o.chain}` : o.chain,
|
|
41881
42001
|
// The flag a user could have typed instead, echoed back so they learn it.
|
|
41882
|
-
preset: `${o.token.toLowerCase()}-${
|
|
42002
|
+
preset: `${o.token.toLowerCase()}-${PRESET_CHAIN[o.chainId]}`
|
|
41883
42003
|
}));
|
|
41884
|
-
function
|
|
42004
|
+
function numbered(rows) {
|
|
42005
|
+
return rows.map((o, i) => ({ number: i + 1, ...o }));
|
|
42006
|
+
}
|
|
42007
|
+
var PICKER_OPTIONS = numbered(PICKER_ROWS);
|
|
42008
|
+
function pickerOptionsFor(isOffered = null) {
|
|
42009
|
+
return numbered(
|
|
42010
|
+
PICKER_ROWS.filter((o) => !o.native || typeof isOffered === "function" && isOffered(o.chainId, o.tokenSymbol))
|
|
42011
|
+
);
|
|
42012
|
+
}
|
|
42013
|
+
function resolvePickerChoice(input, options = PICKER_OPTIONS) {
|
|
41885
42014
|
const raw = String(input ?? "").trim();
|
|
41886
42015
|
if (!raw) throw new CliError("BAD_CHOICE", "Nothing entered. Type the number of a coin.");
|
|
41887
42016
|
if (/^\d+$/.test(raw)) {
|
|
41888
|
-
const option2 =
|
|
42017
|
+
const option2 = options.find((o) => o.number === Number(raw));
|
|
41889
42018
|
if (!option2) {
|
|
41890
42019
|
throw new CliError(
|
|
41891
42020
|
"BAD_CHOICE",
|
|
41892
|
-
`${raw} is not on the list. Choose 1-${
|
|
42021
|
+
`${raw} is not on the list. Choose 1-${options.length}.`
|
|
41893
42022
|
);
|
|
41894
42023
|
}
|
|
41895
42024
|
return { chainId: option2.chainId, tokenSymbol: option2.tokenSymbol, preset: option2.preset };
|
|
@@ -41910,16 +42039,23 @@ var CliError = class extends Error {
|
|
|
41910
42039
|
function listPresets() {
|
|
41911
42040
|
const out2 = [];
|
|
41912
42041
|
for (const s of SUPPORTED_SOURCES) {
|
|
41913
|
-
const chain =
|
|
42042
|
+
const chain = PRESET_CHAIN[s.chainId];
|
|
41914
42043
|
for (const token of s.tokens) out2.push(`${token.toLowerCase()}-${chain}`);
|
|
41915
42044
|
}
|
|
41916
42045
|
return out2;
|
|
41917
42046
|
}
|
|
41918
42047
|
function resolvePreset(preset) {
|
|
41919
|
-
|
|
42048
|
+
let raw = String(preset ?? "").trim().toLowerCase();
|
|
41920
42049
|
if (!raw) {
|
|
41921
42050
|
throw new CliError("MISSING_PRESET", "A coin is required, e.g. --with usdt-solana");
|
|
41922
42051
|
}
|
|
42052
|
+
if (PRESET_SHORTCUTS[raw]) raw = PRESET_SHORTCUTS[raw];
|
|
42053
|
+
if (raw === "eth") {
|
|
42054
|
+
throw new CliError(
|
|
42055
|
+
"BAD_PRESET",
|
|
42056
|
+
"ETH is on more than one chain. Use eth-ethereum, eth-base or eth-arbitrum."
|
|
42057
|
+
);
|
|
42058
|
+
}
|
|
41923
42059
|
const idx = raw.indexOf("-");
|
|
41924
42060
|
if (idx <= 0 || idx === raw.length - 1) {
|
|
41925
42061
|
throw new CliError(
|
|
@@ -42194,7 +42330,8 @@ function parseCliArgs(argv) {
|
|
|
42194
42330
|
};
|
|
42195
42331
|
}
|
|
42196
42332
|
var HELP = `rozo-checkout \u2014 pay a Coinbase Payment Link or a Bitrefill invoice
|
|
42197
|
-
(USDC on Base) with BTC Lightning,
|
|
42333
|
+
(USDC on Base) with BTC Lightning, USDT/USDC on Solana, BNB Chain, Ethereum, Polygon,
|
|
42334
|
+
Arbitrum, Base or Stellar, or a native coin: ETH (Ethereum, Base, Arbitrum), BNB, SOL, POL.
|
|
42198
42335
|
|
|
42199
42336
|
USAGE
|
|
42200
42337
|
npx @rozoai/checkout pay <coinbase-link> (pick a coin from a list)
|
|
@@ -42209,9 +42346,21 @@ USAGE
|
|
|
42209
42346
|
COINS (--with)
|
|
42210
42347
|
usdt-solana usdc-solana usdt-bnb usdc-bnb
|
|
42211
42348
|
usdt-ethereum usdc-ethereum usdt-polygon usdc-polygon
|
|
42212
|
-
usdc-base usdc-stellar
|
|
42349
|
+
usdt-arbitrum usdc-arbitrum usdc-base usdc-stellar
|
|
42350
|
+
btc-lightning
|
|
42351
|
+
native coins: eth-ethereum eth-base eth-arbitrum bnb-bnb (or bnb)
|
|
42352
|
+
sol-solana (or sol) pol-polygon (or pol)
|
|
42213
42353
|
or give them raw: --chain 900 --token USDT
|
|
42214
42354
|
|
|
42355
|
+
NATIVE COINS
|
|
42356
|
+
Offered only when the invoice's quote lists the coin, and only for invoices
|
|
42357
|
+
up to $2,000 (native ETH on Ethereum: $1 minimum). The order is exact-out:
|
|
42358
|
+
send exactly the coin amount shown. Its price is locked only until the time
|
|
42359
|
+
shown (about an hour); after that do not send, start a new order. The coin
|
|
42360
|
+
amount includes an FX spread on top of the service fee, and your wallet also
|
|
42361
|
+
needs a little of the same coin for the network fee. On-chain BTC and Tron
|
|
42362
|
+
are not supported.
|
|
42363
|
+
|
|
42215
42364
|
By default, pay just prints an address for you to pay from any wallet:
|
|
42216
42365
|
no private key, no environment variable, no configuration.
|
|
42217
42366
|
|
|
@@ -42219,10 +42368,12 @@ OPTIONS
|
|
|
42219
42368
|
--with <coin> which coin to pay with. Omit it on a terminal and you get a
|
|
42220
42369
|
numbered list to choose from; scripts and agents must pass it.
|
|
42221
42370
|
--send optional. Sign from a hot wallet instead of paying yourself.
|
|
42222
|
-
The only option that needs a key.
|
|
42223
|
-
|
|
42224
|
-
|
|
42225
|
-
|
|
42371
|
+
The only option that needs a key. EVM and Solana coins only,
|
|
42372
|
+
native ETH, BNB, POL and SOL included (sent as a plain
|
|
42373
|
+
transfer of the exact amount, never after the price lock).
|
|
42374
|
+
On Solana it uses your existing ~/.config/solana/id.json; on
|
|
42375
|
+
EVM an encrypted JSON keystore. A single payment may not
|
|
42376
|
+
exceed $1,100; there is no override.
|
|
42226
42377
|
--keyfile <p> with --send: the key to sign with. A solana-keygen keypair
|
|
42227
42378
|
file, or an encrypted V3 keystore for EVM (passphrase is
|
|
42228
42379
|
prompted, never passed as a flag).
|
|
@@ -42290,6 +42441,296 @@ paid until you confirm, and --send is required before anything is signed.
|
|
|
42290
42441
|
SUPPORT
|
|
42291
42442
|
Email hi@rozo.ai, X https://x.com/ROZOai, Discord https://discord.gg/EfWejgTbuU`;
|
|
42292
42443
|
|
|
42444
|
+
// scripts/src/lib/gas.mjs
|
|
42445
|
+
var EVM_FEE_COIN = Object.freeze({
|
|
42446
|
+
1: { symbol: "ETH", network: "Ethereum" },
|
|
42447
|
+
56: { symbol: "BNB", network: "BNB Chain" },
|
|
42448
|
+
137: { symbol: "POL", network: "Polygon" },
|
|
42449
|
+
8453: { symbol: "ETH", network: "Base" },
|
|
42450
|
+
42161: { symbol: "ETH", network: "Arbitrum" }
|
|
42451
|
+
});
|
|
42452
|
+
var DEFAULT_GAS_BUFFER_PCT = 20;
|
|
42453
|
+
var MAX_GAS_BUFFER_PCT = 200;
|
|
42454
|
+
function gasBufferPct(env = process.env) {
|
|
42455
|
+
const raw = env?.ROZO_CHECKOUT_GAS_BUFFER_PCT;
|
|
42456
|
+
if (raw === void 0 || raw === "") return DEFAULT_GAS_BUFFER_PCT;
|
|
42457
|
+
const n = Number(raw);
|
|
42458
|
+
if (!Number.isInteger(n) || n < 0 || n > MAX_GAS_BUFFER_PCT) return DEFAULT_GAS_BUFFER_PCT;
|
|
42459
|
+
return n;
|
|
42460
|
+
}
|
|
42461
|
+
function formatAtomic(atomic, decimals) {
|
|
42462
|
+
const neg = atomic < 0n;
|
|
42463
|
+
const v = neg ? -atomic : atomic;
|
|
42464
|
+
const base = 10n ** BigInt(decimals);
|
|
42465
|
+
const whole = v / base;
|
|
42466
|
+
const frac = (v % base).toString().padStart(decimals, "0").replace(/0+$/, "");
|
|
42467
|
+
return `${neg ? "-" : ""}${whole}${frac ? `.${frac}` : ""}`;
|
|
42468
|
+
}
|
|
42469
|
+
function evmFeeRequirement({ gasEstimate, maxFeePerGas, gasPrice, bufferPct = DEFAULT_GAS_BUFFER_PCT }) {
|
|
42470
|
+
const perGas = typeof maxFeePerGas === "bigint" ? maxFeePerGas : typeof gasPrice === "bigint" ? gasPrice : null;
|
|
42471
|
+
if (typeof gasEstimate !== "bigint" || perGas === null) return null;
|
|
42472
|
+
const gasLimit = (gasEstimate * BigInt(100 + bufferPct) + 99n) / 100n;
|
|
42473
|
+
return { gasLimit, perGas, pricing: typeof maxFeePerGas === "bigint" ? "eip1559" : "legacy", fee: gasLimit * perGas };
|
|
42474
|
+
}
|
|
42475
|
+
function assessFee({ balance, required, decimals, symbol, network }) {
|
|
42476
|
+
const ok = required === null ? balance > 0n : balance >= required;
|
|
42477
|
+
const details = {
|
|
42478
|
+
network,
|
|
42479
|
+
feeCoin: symbol,
|
|
42480
|
+
balance: formatAtomic(balance, decimals),
|
|
42481
|
+
required: required === null ? null : formatAtomic(required, decimals),
|
|
42482
|
+
shortfall: required === null || ok ? null : formatAtomic(required - balance, decimals)
|
|
42483
|
+
};
|
|
42484
|
+
return { ok, details };
|
|
42485
|
+
}
|
|
42486
|
+
function insufficient(details, extra) {
|
|
42487
|
+
const need = details.required ? `about ${details.required} ${details.feeCoin}` : `some ${details.feeCoin}`;
|
|
42488
|
+
const forWhat = details.payment ? `for the payment of ${details.payment} ${details.feeCoin} plus the network fee` : "for the network fee";
|
|
42489
|
+
return new SkillError(
|
|
42490
|
+
"INSUFFICIENT_GAS",
|
|
42491
|
+
`This wallet holds ${details.balance} ${details.feeCoin} on ${details.network} but needs ${need} ${forWhat}${details.shortfall ? ` (short by ${details.shortfall} ${details.feeCoin})` : ""}. Nothing was signed. Add ${details.feeCoin} on ${details.network} to this wallet and re-run, or pay with a different coin.` + (extra ? ` ${extra}` : ""),
|
|
42492
|
+
details
|
|
42493
|
+
);
|
|
42494
|
+
}
|
|
42495
|
+
function unavailable(network, err) {
|
|
42496
|
+
return new SkillError(
|
|
42497
|
+
"GAS_CHECK_UNAVAILABLE",
|
|
42498
|
+
`Could not check the network fee on ${network}: ${redact(err?.shortMessage || err?.message || "unknown error")}. This is not evidence of a shortfall. Nothing was signed. Retry, pass --rpc <url>, or pay by hand from your wallet.`,
|
|
42499
|
+
{ network }
|
|
42500
|
+
);
|
|
42501
|
+
}
|
|
42502
|
+
async function estimateFees(client) {
|
|
42503
|
+
try {
|
|
42504
|
+
return await client.estimateFeesPerGas();
|
|
42505
|
+
} catch (err) {
|
|
42506
|
+
if (err?.name !== "Eip1559FeesNotSupportedError") throw err;
|
|
42507
|
+
return client.estimateFeesPerGas({ type: "legacy" });
|
|
42508
|
+
}
|
|
42509
|
+
}
|
|
42510
|
+
var OP_STACK_GAS_PRICE_ORACLE = "0x420000000000000000000000000000000000000F";
|
|
42511
|
+
var OP_STACK_CHAIN_IDS = /* @__PURE__ */ new Set([8453]);
|
|
42512
|
+
async function evmGasPrecheck({
|
|
42513
|
+
client,
|
|
42514
|
+
chainId,
|
|
42515
|
+
from: from15,
|
|
42516
|
+
to,
|
|
42517
|
+
data,
|
|
42518
|
+
value = 0n,
|
|
42519
|
+
bufferPct = gasBufferPct(),
|
|
42520
|
+
estimateL1Fee: estimateL1Fee2 = null
|
|
42521
|
+
}) {
|
|
42522
|
+
const coin = EVM_FEE_COIN[Number(chainId)] ?? { symbol: "native coin", network: `chain ${chainId}` };
|
|
42523
|
+
let balance;
|
|
42524
|
+
try {
|
|
42525
|
+
balance = await client.getBalance({ address: from15 });
|
|
42526
|
+
} catch (err) {
|
|
42527
|
+
throw unavailable(coin.network, err);
|
|
42528
|
+
}
|
|
42529
|
+
let gasEstimate;
|
|
42530
|
+
let fees;
|
|
42531
|
+
try {
|
|
42532
|
+
gasEstimate = await client.estimateGas({ account: from15, to, data, value });
|
|
42533
|
+
fees = await estimateFees(client);
|
|
42534
|
+
} catch (err) {
|
|
42535
|
+
if (balance === 0n) {
|
|
42536
|
+
throw insufficient(
|
|
42537
|
+
assessFee({ balance, required: null, decimals: 18, symbol: coin.symbol, network: coin.network }).details
|
|
42538
|
+
);
|
|
42539
|
+
}
|
|
42540
|
+
throw unavailable(coin.network, err);
|
|
42541
|
+
}
|
|
42542
|
+
const req = evmFeeRequirement({
|
|
42543
|
+
gasEstimate,
|
|
42544
|
+
maxFeePerGas: fees?.maxFeePerGas,
|
|
42545
|
+
gasPrice: fees?.gasPrice,
|
|
42546
|
+
bufferPct
|
|
42547
|
+
});
|
|
42548
|
+
if (!req) throw unavailable(coin.network, new Error("the node returned no fee price"));
|
|
42549
|
+
let l1Fee = 0n;
|
|
42550
|
+
if (OP_STACK_CHAIN_IDS.has(Number(chainId))) {
|
|
42551
|
+
if (typeof estimateL1Fee2 !== "function") {
|
|
42552
|
+
throw unavailable(coin.network, new Error("no L1 data fee estimator for this OP-stack chain"));
|
|
42553
|
+
}
|
|
42554
|
+
try {
|
|
42555
|
+
l1Fee = (await estimateL1Fee2() * BigInt(100 + bufferPct) + 99n) / 100n;
|
|
42556
|
+
} catch (err) {
|
|
42557
|
+
throw unavailable(coin.network, err);
|
|
42558
|
+
}
|
|
42559
|
+
}
|
|
42560
|
+
const required = req.fee + l1Fee + value;
|
|
42561
|
+
const { ok, details } = assessFee({ balance, required, decimals: 18, symbol: coin.symbol, network: coin.network });
|
|
42562
|
+
const full = {
|
|
42563
|
+
...details,
|
|
42564
|
+
payment: value > 0n ? formatAtomic(value, 18) : null,
|
|
42565
|
+
gasLimit: req.gasLimit.toString(),
|
|
42566
|
+
pricing: req.pricing,
|
|
42567
|
+
bufferPct,
|
|
42568
|
+
l1DataFee: OP_STACK_CHAIN_IDS.has(Number(chainId)) ? formatAtomic(l1Fee, 18) : null
|
|
42569
|
+
};
|
|
42570
|
+
if (!ok) throw insufficient(full);
|
|
42571
|
+
return full;
|
|
42572
|
+
}
|
|
42573
|
+
var LAMPORTS_DECIMALS = 9;
|
|
42574
|
+
async function solFeePrecheck({ connection, payer, message, value = 0n }) {
|
|
42575
|
+
const network = "Solana";
|
|
42576
|
+
let balance;
|
|
42577
|
+
let fee;
|
|
42578
|
+
let rentMin;
|
|
42579
|
+
try {
|
|
42580
|
+
balance = BigInt(await connection.getBalance(payer, "confirmed"));
|
|
42581
|
+
const res = await connection.getFeeForMessage(message, "confirmed");
|
|
42582
|
+
if (res?.value === null || res?.value === void 0) {
|
|
42583
|
+
throw new Error("the node returned no fee for this transaction (stale blockhash?)");
|
|
42584
|
+
}
|
|
42585
|
+
fee = BigInt(res.value);
|
|
42586
|
+
rentMin = BigInt(await connection.getMinimumBalanceForRentExemption(0));
|
|
42587
|
+
} catch (err) {
|
|
42588
|
+
if (balance === 0n) {
|
|
42589
|
+
throw insufficient(
|
|
42590
|
+
assessFee({ balance, required: null, decimals: LAMPORTS_DECIMALS, symbol: "SOL", network }).details
|
|
42591
|
+
);
|
|
42592
|
+
}
|
|
42593
|
+
throw unavailable(network, err);
|
|
42594
|
+
}
|
|
42595
|
+
const remaining = balance - fee - value;
|
|
42596
|
+
const required = remaining === 0n ? fee + value : fee + value + rentMin;
|
|
42597
|
+
const { ok, details } = assessFee({ balance, required, decimals: LAMPORTS_DECIMALS, symbol: "SOL", network });
|
|
42598
|
+
const full = {
|
|
42599
|
+
...details,
|
|
42600
|
+
payment: value > 0n ? formatAtomic(value, LAMPORTS_DECIMALS) : null,
|
|
42601
|
+
fee: formatAtomic(fee, LAMPORTS_DECIMALS),
|
|
42602
|
+
rentExemptMinimum: formatAtomic(rentMin, LAMPORTS_DECIMALS)
|
|
42603
|
+
};
|
|
42604
|
+
if (!ok) {
|
|
42605
|
+
throw insufficient(
|
|
42606
|
+
full,
|
|
42607
|
+
balance >= fee + value ? "Solana also requires a wallet to keep a small minimum balance after paying the fee." : null
|
|
42608
|
+
);
|
|
42609
|
+
}
|
|
42610
|
+
return full;
|
|
42611
|
+
}
|
|
42612
|
+
|
|
42613
|
+
// scripts/src/lib/rpc.mjs
|
|
42614
|
+
var DEFAULT_RPC = Object.freeze({
|
|
42615
|
+
// eth.llamarpc.com and polygon-rpc.com stopped answering (checked
|
|
42616
|
+
// 2026-10-12: HTTP 525, and "API key disabled"); publicnode serves both.
|
|
42617
|
+
1: "https://ethereum-rpc.publicnode.com",
|
|
42618
|
+
56: "https://bsc-dataseed.binance.org",
|
|
42619
|
+
137: "https://polygon-bor-rpc.publicnode.com",
|
|
42620
|
+
8453: "https://mainnet.base.org",
|
|
42621
|
+
42161: "https://arb1.arbitrum.io/rpc",
|
|
42622
|
+
900: "https://api.mainnet-beta.solana.com"
|
|
42623
|
+
});
|
|
42624
|
+
function rpcFor(chainId, override, env = process.env) {
|
|
42625
|
+
if (override && override !== true) return String(override);
|
|
42626
|
+
const fromEnv = env?.[`ROZO_CHECKOUT_RPC_${chainId}`];
|
|
42627
|
+
if (fromEnv) return fromEnv;
|
|
42628
|
+
const fallback = DEFAULT_RPC[String(chainId)];
|
|
42629
|
+
if (!fallback) {
|
|
42630
|
+
throw new SkillError(
|
|
42631
|
+
"NO_RPC",
|
|
42632
|
+
`No RPC known for chain ${chainId}. Pass --rpc <url> or set ROZO_CHECKOUT_RPC_${chainId}.`
|
|
42633
|
+
);
|
|
42634
|
+
}
|
|
42635
|
+
return fallback;
|
|
42636
|
+
}
|
|
42637
|
+
|
|
42638
|
+
// scripts/src/lib/native.mjs
|
|
42639
|
+
var NATIVE_BALANCE_TIMEOUT_MS = 3e3;
|
|
42640
|
+
var EVM_HEADROOM_GAS = 100000n;
|
|
42641
|
+
var SOL_HEADROOM_LAMPORTS = 1000000n;
|
|
42642
|
+
function nativeDepositWarnings({ tokenSymbol, chainId }) {
|
|
42643
|
+
const coin = String(tokenSymbol || "").toUpperCase();
|
|
42644
|
+
return [
|
|
42645
|
+
`This is an exact-out ${coin} order: send exactly the amount shown, in one transfer. The coin price is locked only until the time shown; after that, do not send, start a new order.`,
|
|
42646
|
+
`The ${coin} amount includes an FX spread on top of the service fee.`,
|
|
42647
|
+
`Your wallet also needs some ${coin} on ${chainName(chainId)} for the network fee, on top of the amount shown.`,
|
|
42648
|
+
"Paying from an exchange: make sure the amount that ARRIVES is exactly the amount shown. Exchanges often subtract their withdrawal fee, and a short payment may need manual review."
|
|
42649
|
+
];
|
|
42650
|
+
}
|
|
42651
|
+
function nativeCoinsForFamily(family, isOffered = null) {
|
|
42652
|
+
return Object.values(NATIVE_COINS).filter(
|
|
42653
|
+
(c2) => chainFamily(c2.chainId) === family && (typeof isOffered !== "function" || isOffered(c2.chainId, c2.symbol))
|
|
42654
|
+
);
|
|
42655
|
+
}
|
|
42656
|
+
async function rpcCall(fetchImpl, url, method, params, signal) {
|
|
42657
|
+
const res = await fetchImpl(url, {
|
|
42658
|
+
method: "POST",
|
|
42659
|
+
headers: { "content-type": "application/json", accept: "application/json" },
|
|
42660
|
+
body: JSON.stringify({ jsonrpc: "2.0", id: 1, method, params }),
|
|
42661
|
+
signal
|
|
42662
|
+
});
|
|
42663
|
+
if (!res.ok) throw new Error(`HTTP ${res.status}`);
|
|
42664
|
+
const json = await res.json();
|
|
42665
|
+
if (json?.error) throw new Error(String(json.error?.message ?? "rpc error"));
|
|
42666
|
+
return json?.result;
|
|
42667
|
+
}
|
|
42668
|
+
function hexToBigInt(value) {
|
|
42669
|
+
if (typeof value !== "string" || !/^0x[0-9a-fA-F]+$/.test(value)) {
|
|
42670
|
+
throw new Error("not a hex quantity");
|
|
42671
|
+
}
|
|
42672
|
+
return BigInt(value);
|
|
42673
|
+
}
|
|
42674
|
+
async function fetchNativeBalance({
|
|
42675
|
+
chainId,
|
|
42676
|
+
address,
|
|
42677
|
+
fetchImpl = globalThis.fetch,
|
|
42678
|
+
timeoutMs = NATIVE_BALANCE_TIMEOUT_MS,
|
|
42679
|
+
env = process.env
|
|
42680
|
+
}) {
|
|
42681
|
+
const coin = Object.values(NATIVE_COINS).find((c2) => c2.chainId === String(chainId));
|
|
42682
|
+
if (!coin) return { ok: false, chainId: String(chainId), reason: "not a native coin chain" };
|
|
42683
|
+
const base = { chainId: coin.chainId, tokenSymbol: coin.symbol, decimals: coin.decimals };
|
|
42684
|
+
let url;
|
|
42685
|
+
try {
|
|
42686
|
+
url = rpcFor(coin.chainId, null, env);
|
|
42687
|
+
} catch (err) {
|
|
42688
|
+
return { ...base, ok: false, reason: err.message };
|
|
42689
|
+
}
|
|
42690
|
+
const controller = new AbortController();
|
|
42691
|
+
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
42692
|
+
try {
|
|
42693
|
+
if (chainFamily(coin.chainId) === "solana") {
|
|
42694
|
+
const r = await rpcCall(fetchImpl, url, "getBalance", [address, { commitment: "confirmed" }], controller.signal);
|
|
42695
|
+
const lamports = r?.value;
|
|
42696
|
+
if (!Number.isSafeInteger(lamports) || lamports < 0) throw new Error("bad balance");
|
|
42697
|
+
return { ...base, ok: true, balanceAtomic: BigInt(lamports), headroomAtomic: SOL_HEADROOM_LAMPORTS };
|
|
42698
|
+
}
|
|
42699
|
+
const [bal, gasPrice] = await Promise.all([
|
|
42700
|
+
rpcCall(fetchImpl, url, "eth_getBalance", [address, "latest"], controller.signal),
|
|
42701
|
+
rpcCall(fetchImpl, url, "eth_gasPrice", [], controller.signal)
|
|
42702
|
+
]);
|
|
42703
|
+
const balanceAtomic = hexToBigInt(bal);
|
|
42704
|
+
const headroomAtomic = hexToBigInt(gasPrice) * EVM_HEADROOM_GAS * 120n / 100n;
|
|
42705
|
+
return { ...base, ok: true, balanceAtomic, headroomAtomic };
|
|
42706
|
+
} catch (err) {
|
|
42707
|
+
return {
|
|
42708
|
+
...base,
|
|
42709
|
+
ok: false,
|
|
42710
|
+
reason: err?.name === "AbortError" ? "balance check timed out" : "balance check unavailable"
|
|
42711
|
+
};
|
|
42712
|
+
} finally {
|
|
42713
|
+
clearTimeout(timer);
|
|
42714
|
+
}
|
|
42715
|
+
}
|
|
42716
|
+
async function fetchNativeBalances({ address, family, isOffered = null, ...rest }) {
|
|
42717
|
+
const coins = nativeCoinsForFamily(family, isOffered);
|
|
42718
|
+
return Promise.all(coins.map((c2) => fetchNativeBalance({ chainId: c2.chainId, address, ...rest })));
|
|
42719
|
+
}
|
|
42720
|
+
function assessNative({ balanceAtomic, headroomAtomic, amountAtomic = null }) {
|
|
42721
|
+
if (amountAtomic === null || amountAtomic === void 0) {
|
|
42722
|
+
if (balanceAtomic <= headroomAtomic) return { mark: "insufficient", provable: balanceAtomic === 0n };
|
|
42723
|
+
return { mark: "held", provable: false };
|
|
42724
|
+
}
|
|
42725
|
+
if (balanceAtomic < amountAtomic) return { mark: "insufficient", provable: true };
|
|
42726
|
+
if (balanceAtomic < amountAtomic + headroomAtomic) return { mark: "tight", provable: false };
|
|
42727
|
+
return { mark: "affordable", provable: false };
|
|
42728
|
+
}
|
|
42729
|
+
function formatNativeHeld(result) {
|
|
42730
|
+
if (!result?.ok) return null;
|
|
42731
|
+
return `${formatAtomic(result.balanceAtomic, result.decimals)} ${result.tokenSymbol}`;
|
|
42732
|
+
}
|
|
42733
|
+
|
|
42293
42734
|
// scripts/src/lib/wallet-check.mjs
|
|
42294
42735
|
var INTENT_API_BASE = process.env.ROZO_CHECKOUT_INTENT_API || "https://intentapi.rozo.ai";
|
|
42295
42736
|
var BALANCE_TIMEOUT_MS = 3e3;
|
|
@@ -42366,13 +42807,28 @@ function parsePaymentOptions(json) {
|
|
|
42366
42807
|
}
|
|
42367
42808
|
return out2;
|
|
42368
42809
|
}
|
|
42369
|
-
function markPickerOptions(pickerOptions, { family = null, options = [] } = {}) {
|
|
42810
|
+
function markPickerOptions(pickerOptions, { family = null, options = [], native = [], ok = true } = {}) {
|
|
42370
42811
|
const index2 = /* @__PURE__ */ new Map();
|
|
42371
42812
|
for (const o of options) index2.set(`${o.chainId}:${o.tokenSymbol}`, o);
|
|
42813
|
+
const nativeIndex = /* @__PURE__ */ new Map();
|
|
42814
|
+
for (const n of native ?? []) if (n?.chainId) nativeIndex.set(String(n.chainId), n);
|
|
42372
42815
|
const marked = pickerOptions.map((row) => {
|
|
42373
42816
|
if (!family || !familyCoversChain(family, row.chainId)) {
|
|
42374
42817
|
return { ...row, mark: "unchecked", balanceUsd: null, note: null };
|
|
42375
42818
|
}
|
|
42819
|
+
if (isNativeSource(row.chainId, row.tokenSymbol)) {
|
|
42820
|
+
const n = nativeIndex.get(String(row.chainId));
|
|
42821
|
+
if (!n || !n.ok) return { ...row, mark: "unchecked", balanceUsd: null, note: n?.reason ?? null };
|
|
42822
|
+
const verdict = assessNative({ balanceAtomic: n.balanceAtomic, headroomAtomic: n.headroomAtomic });
|
|
42823
|
+
return {
|
|
42824
|
+
...row,
|
|
42825
|
+
mark: verdict.mark,
|
|
42826
|
+
balanceUsd: null,
|
|
42827
|
+
held: formatNativeHeld(n),
|
|
42828
|
+
note: verdict.mark === "insufficient" ? "not enough to cover the network fee" : null
|
|
42829
|
+
};
|
|
42830
|
+
}
|
|
42831
|
+
if (ok === false) return { ...row, mark: "unchecked", balanceUsd: null, note: null };
|
|
42376
42832
|
const hit = index2.get(`${row.chainId}:${row.tokenSymbol}`);
|
|
42377
42833
|
if (!hit) {
|
|
42378
42834
|
return { ...row, mark: "insufficient", balanceUsd: 0, note: "no balance found" };
|
|
@@ -42384,7 +42840,7 @@ function markPickerOptions(pickerOptions, { family = null, options = [] } = {})
|
|
|
42384
42840
|
note: hit.disabledReason
|
|
42385
42841
|
};
|
|
42386
42842
|
});
|
|
42387
|
-
const rank = { affordable: 0,
|
|
42843
|
+
const rank = { affordable: 0, held: 1, unchecked: 2, insufficient: 3 };
|
|
42388
42844
|
return marked.map((row, i) => ({ row, i })).sort((a, b) => rank[a.row.mark] - rank[b.row.mark] || a.i - b.i).map(({ row }) => row);
|
|
42389
42845
|
}
|
|
42390
42846
|
async function fetchWalletOptions({ address, usdRequired, timeoutMs = BALANCE_TIMEOUT_MS }) {
|
|
@@ -42563,6 +43019,8 @@ function createOrderRecordUnlocked(record) {
|
|
|
42563
43019
|
amount: record.amount,
|
|
42564
43020
|
amountUnit: record.amountUnit ?? null,
|
|
42565
43021
|
expiresAt: record.expiresAt ?? null,
|
|
43022
|
+
// Native coin orders only: the price lock the backend reported at create.
|
|
43023
|
+
quoteExpiresAt: record.quoteExpiresAt ?? existing?.quoteExpiresAt ?? null,
|
|
42566
43024
|
createdAt: existing?.createdAt ?? (/* @__PURE__ */ new Date()).toISOString(),
|
|
42567
43025
|
updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
42568
43026
|
confirmation: existing?.confirmation ?? null,
|
|
@@ -42584,7 +43042,7 @@ function depositDigest(source) {
|
|
|
42584
43042
|
});
|
|
42585
43043
|
return crypto2.createHash("sha256").update(canonical, "utf8").digest("hex");
|
|
42586
43044
|
}
|
|
42587
|
-
function recordConfirmation(rozoPaymentId, { source, invoiceAmount, tier }) {
|
|
43045
|
+
function recordConfirmation(rozoPaymentId, { source, invoiceAmount, tier, quoteExpiresAt = null }) {
|
|
42588
43046
|
return withLock(() => {
|
|
42589
43047
|
const state = readState(rozoPaymentId);
|
|
42590
43048
|
if (!state) {
|
|
@@ -42597,7 +43055,10 @@ function recordConfirmation(rozoPaymentId, { source, invoiceAmount, tier }) {
|
|
|
42597
43055
|
confirmedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
42598
43056
|
depositDigest: depositDigest(source),
|
|
42599
43057
|
invoiceAmount: invoiceAmount ?? state.invoiceAmount ?? null,
|
|
42600
|
-
tier: tier ?? null
|
|
43058
|
+
tier: tier ?? null,
|
|
43059
|
+
// The native price lock the human was shown. A send never goes out
|
|
43060
|
+
// after it, even if the backend later reports a later one.
|
|
43061
|
+
quoteExpiresAt: quoteExpiresAt ?? null
|
|
42601
43062
|
}
|
|
42602
43063
|
};
|
|
42603
43064
|
writeAtomic(statePath(rozoPaymentId), next);
|
|
@@ -42629,6 +43090,7 @@ function claimSend(rozoPaymentId, intent, { skipCaps = false } = {}) {
|
|
|
42629
43090
|
claimedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
42630
43091
|
chainId: intent.chainId,
|
|
42631
43092
|
tokenSymbol: intent.tokenSymbol,
|
|
43093
|
+
native: Boolean(intent.native),
|
|
42632
43094
|
from: intent.from,
|
|
42633
43095
|
to: intent.to,
|
|
42634
43096
|
amountAtomic: intent.amountAtomic,
|
|
@@ -42914,6 +43376,7 @@ var MARGINS_MS = {
|
|
|
42914
43376
|
56: 10 * MINUTE,
|
|
42915
43377
|
137: 10 * MINUTE,
|
|
42916
43378
|
8453: 10 * MINUTE,
|
|
43379
|
+
42161: 10 * MINUTE,
|
|
42917
43380
|
900: 5 * MINUTE,
|
|
42918
43381
|
1500: 10 * MINUTE,
|
|
42919
43382
|
lightning: 10 * MINUTE
|
|
@@ -42931,8 +43394,10 @@ function lightningWatchMs(expiresAt, { now = Date.now(), fallbackMs = DEFAULT_WA
|
|
|
42931
43394
|
}
|
|
42932
43395
|
function settlementWatchSeconds(opts, deposit, now = Date.now()) {
|
|
42933
43396
|
const fallbackMs = Number(opts.timeout ?? 900) * 1e3;
|
|
42934
|
-
if (opts.timeoutExplicit
|
|
42935
|
-
|
|
43397
|
+
if (opts.timeoutExplicit) return Math.round(fallbackMs / 1e3);
|
|
43398
|
+
const until = deposit?.lnInvoice ? deposit.expiresAt : deposit?.quoteExpiresAt;
|
|
43399
|
+
if (!until) return Math.round(fallbackMs / 1e3);
|
|
43400
|
+
return Math.ceil(lightningWatchMs(until, { now, fallbackMs }) / 1e3);
|
|
42936
43401
|
}
|
|
42937
43402
|
function minutesRemaining(expiresAt, now = Date.now()) {
|
|
42938
43403
|
const at = parseDeadline(expiresAt);
|
|
@@ -42986,13 +43451,16 @@ function checkExpiry({
|
|
|
42986
43451
|
chainId,
|
|
42987
43452
|
intentExpiresAt,
|
|
42988
43453
|
coinbaseExpiry,
|
|
42989
|
-
bolt11ExpiresAt = void 0
|
|
43454
|
+
bolt11ExpiresAt = void 0,
|
|
43455
|
+
quoteExpiresAt = void 0
|
|
42990
43456
|
}) {
|
|
42991
43457
|
const marginMs = marginFor(chainId);
|
|
42992
43458
|
const intentMs = parseDeadline(intentExpiresAt);
|
|
42993
43459
|
const coinbaseMs = parseDeadline(coinbaseExpiry);
|
|
42994
43460
|
const bolt11Ms = bolt11ExpiresAt === void 0 ? void 0 : parseDeadline(bolt11ExpiresAt);
|
|
42995
|
-
const
|
|
43461
|
+
const native = quoteExpiresAt !== void 0;
|
|
43462
|
+
const quoteMs = native ? parseDeadline(quoteExpiresAt) : null;
|
|
43463
|
+
const deadlines = { intentMs, coinbaseMs, bolt11Ms: bolt11Ms ?? null, quoteMs };
|
|
42996
43464
|
const base = {
|
|
42997
43465
|
marginMs,
|
|
42998
43466
|
effectiveDeadlineMs: null,
|
|
@@ -43016,7 +43484,16 @@ function checkExpiry({
|
|
|
43016
43484
|
reason: "Coinbase preApprovalExpiry is missing or unparsable."
|
|
43017
43485
|
};
|
|
43018
43486
|
}
|
|
43019
|
-
|
|
43487
|
+
if (native && quoteMs === null) {
|
|
43488
|
+
return {
|
|
43489
|
+
...base,
|
|
43490
|
+
ok: false,
|
|
43491
|
+
code: "EXPIRY_UNPARSABLE",
|
|
43492
|
+
reason: "This native coin order carries no price lock (quoteExpiresAt), so the coin amount cannot be trusted to be honoured. Refusing to treat it as payable."
|
|
43493
|
+
};
|
|
43494
|
+
}
|
|
43495
|
+
const effective = native ? Math.min(intentMs, coinbaseMs, quoteMs) : Math.min(intentMs, coinbaseMs);
|
|
43496
|
+
const lockBinds = native && quoteMs <= Math.min(intentMs, coinbaseMs);
|
|
43020
43497
|
const msRemaining = effective - now;
|
|
43021
43498
|
const msOfSlack = msRemaining - marginMs;
|
|
43022
43499
|
const withDeadline = {
|
|
@@ -43029,16 +43506,16 @@ function checkExpiry({
|
|
|
43029
43506
|
return {
|
|
43030
43507
|
...withDeadline,
|
|
43031
43508
|
ok: false,
|
|
43032
|
-
code: "EXPIRED",
|
|
43033
|
-
reason: "The order or the Coinbase link has already expired."
|
|
43509
|
+
code: lockBinds ? "QUOTE_EXPIRED" : "EXPIRED",
|
|
43510
|
+
reason: lockBinds ? "The coin price for this order was locked until quoteExpiresAt, and that has passed. A payment now would be valued at the price when it arrives and may fall short. Do not send it; let the order expire unfunded and start a new one." : "The order or the Coinbase link has already expired."
|
|
43034
43511
|
};
|
|
43035
43512
|
}
|
|
43036
43513
|
if (msOfSlack <= 0) {
|
|
43037
43514
|
return {
|
|
43038
43515
|
...withDeadline,
|
|
43039
43516
|
ok: false,
|
|
43040
|
-
code: "EXPIRY_MARGIN",
|
|
43041
|
-
reason: `Only ${Math.floor(msRemaining / 1e3)}s left before the earliest deadline; this chain needs a ${Math.floor(marginMs / 6e4)} min safety margin.`
|
|
43517
|
+
code: lockBinds ? "QUOTE_EXPIRY_MARGIN" : "EXPIRY_MARGIN",
|
|
43518
|
+
reason: `Only ${Math.floor(msRemaining / 1e3)}s left before the earliest deadline${lockBinds ? " (the coin price lock)" : ""}; this chain needs a ${Math.floor(marginMs / 6e4)} min safety margin.`
|
|
43042
43519
|
};
|
|
43043
43520
|
}
|
|
43044
43521
|
if (bolt11ExpiresAt !== void 0) {
|
|
@@ -43062,6 +43539,12 @@ function checkExpiry({
|
|
|
43062
43539
|
}
|
|
43063
43540
|
return { ...withDeadline, ok: true, code: null, reason: null };
|
|
43064
43541
|
}
|
|
43542
|
+
function priceLockFor({ native, payment = null, others = [] }) {
|
|
43543
|
+
if (!native) return void 0;
|
|
43544
|
+
const candidates = [payment?.quoteExpiresAt, payment?.source?.quoteExpiresAt, ...others].map(parseDeadline).filter((ms) => ms !== null);
|
|
43545
|
+
if (!candidates.length) return null;
|
|
43546
|
+
return new Date(Math.min(...candidates)).toISOString();
|
|
43547
|
+
}
|
|
43065
43548
|
|
|
43066
43549
|
// scripts/src/lib/key-source.mjs
|
|
43067
43550
|
import fs6 from "node:fs";
|
|
@@ -43248,7 +43731,7 @@ async function recoverPublicKey({ hash: hash3, signature }) {
|
|
|
43248
43731
|
const { r, s, v, yParity } = signature;
|
|
43249
43732
|
const yParityOrV2 = Number(yParity ?? v);
|
|
43250
43733
|
const recoveryBit2 = toRecoveryBit(yParityOrV2);
|
|
43251
|
-
return new secp256k13.Signature(
|
|
43734
|
+
return new secp256k13.Signature(hexToBigInt2(r), hexToBigInt2(s)).addRecoveryBit(recoveryBit2);
|
|
43252
43735
|
}
|
|
43253
43736
|
const signatureHex = isHex(signature) ? signature : toHex(signature);
|
|
43254
43737
|
if (size(signatureHex) !== 65)
|
|
@@ -43661,7 +44144,7 @@ async function internal_estimateMaxPriorityFeePerGas(client, args) {
|
|
|
43661
44144
|
const maxPriorityFeePerGasHex = await client.request({
|
|
43662
44145
|
method: "eth_maxPriorityFeePerGas"
|
|
43663
44146
|
});
|
|
43664
|
-
return
|
|
44147
|
+
return hexToBigInt2(maxPriorityFeePerGasHex);
|
|
43665
44148
|
} catch {
|
|
43666
44149
|
const [block, gasPrice] = await Promise.all([
|
|
43667
44150
|
block_ ? Promise.resolve(block_) : getAction(client, getBlock, "getBlock")({}),
|
|
@@ -45588,7 +46071,7 @@ async function sendCalls(client, parameters) {
|
|
|
45588
46071
|
chain,
|
|
45589
46072
|
data: call2.data,
|
|
45590
46073
|
to: call2.to,
|
|
45591
|
-
value: call2.value ?
|
|
46074
|
+
value: call2.value ? hexToBigInt2(call2.value) : void 0
|
|
45592
46075
|
});
|
|
45593
46076
|
results.push({ status: "fulfilled", value });
|
|
45594
46077
|
} catch (reason) {
|
|
@@ -45675,8 +46158,8 @@ async function getCallsStatus(client, parameters) {
|
|
|
45675
46158
|
chainId: chainId ? hexToNumber(chainId) : void 0,
|
|
45676
46159
|
receipts: receipts?.map((receipt) => ({
|
|
45677
46160
|
...receipt,
|
|
45678
|
-
blockNumber:
|
|
45679
|
-
gasUsed:
|
|
46161
|
+
blockNumber: hexToBigInt2(receipt.blockNumber),
|
|
46162
|
+
gasUsed: hexToBigInt2(receipt.gasUsed),
|
|
45680
46163
|
status: receiptStatuses[receipt.status]
|
|
45681
46164
|
})) ?? [],
|
|
45682
46165
|
statusCode,
|
|
@@ -51885,10 +52368,10 @@ async function simulateCalls(client, parameters) {
|
|
|
51885
52368
|
const results = block_calls.slice(0, -1) ?? [];
|
|
51886
52369
|
const ethPre = block_ethPre?.calls ?? [];
|
|
51887
52370
|
const assetsPre = block_assetsPre?.calls ?? [];
|
|
51888
|
-
const balancesPre = [...ethPre, ...assetsPre].map((call2) => call2.status === "success" ?
|
|
52371
|
+
const balancesPre = [...ethPre, ...assetsPre].map((call2) => call2.status === "success" ? hexToBigInt2(call2.data) : null);
|
|
51889
52372
|
const ethPost = block_ethPost?.calls ?? [];
|
|
51890
52373
|
const assetsPost = block_assetsPost?.calls ?? [];
|
|
51891
|
-
const balancesPost = [...ethPost, ...assetsPost].map((call2) => call2.status === "success" ?
|
|
52374
|
+
const balancesPost = [...ethPost, ...assetsPost].map((call2) => call2.status === "success" ? hexToBigInt2(call2.data) : null);
|
|
51892
52375
|
const decimals = (block_decimals?.calls ?? []).map((x) => x.status === "success" ? x.result : null);
|
|
51893
52376
|
const symbols = (block_symbols?.calls ?? []).map((x) => x.status === "success" ? x.result : null);
|
|
51894
52377
|
const tokenURI = (block_tokenURI?.calls ?? []).map((x) => x.status === "success" ? x.result : null);
|
|
@@ -52061,7 +52544,7 @@ function serializeSignature({ r, s, to = "hex", v, yParity }) {
|
|
|
52061
52544
|
return v % 2n === 0n ? 1 : 0;
|
|
52062
52545
|
throw new Error("Invalid `v` or `yParity` value");
|
|
52063
52546
|
})();
|
|
52064
|
-
const signature = `0x${new secp256k1.Signature(
|
|
52547
|
+
const signature = `0x${new secp256k1.Signature(hexToBigInt2(r), hexToBigInt2(s)).toCompactHex()}${yParity_ === 0 ? "1b" : "1c"}`;
|
|
52065
52548
|
if (to === "hex")
|
|
52066
52549
|
return signature;
|
|
52067
52550
|
return hexToBytes(signature);
|
|
@@ -52346,7 +52829,7 @@ function watchBlockNumber(client, { emitOnBegin = false, emitMissed = false, onB
|
|
|
52346
52829
|
onData(data) {
|
|
52347
52830
|
if (!active)
|
|
52348
52831
|
return;
|
|
52349
|
-
const blockNumber =
|
|
52832
|
+
const blockNumber = hexToBigInt2(data.result?.number);
|
|
52350
52833
|
emit2.onBlockNumber(blockNumber, prevBlockNumber);
|
|
52351
52834
|
prevBlockNumber = blockNumber;
|
|
52352
52835
|
},
|
|
@@ -54911,6 +55394,13 @@ function snapshotFromQuote(quote) {
|
|
|
54911
55394
|
|
|
54912
55395
|
// scripts/src/lib/guards.mjs
|
|
54913
55396
|
var UNPAID_STATUS = "payment_unpaid";
|
|
55397
|
+
var NATIVE_PROGRESS_STATUSES = /* @__PURE__ */ new Set([
|
|
55398
|
+
"payment_payin_completed",
|
|
55399
|
+
"payment_bridging",
|
|
55400
|
+
"payment_payout_started",
|
|
55401
|
+
"payment_payout_completed",
|
|
55402
|
+
"payment_completed"
|
|
55403
|
+
]);
|
|
54914
55404
|
function receiptSignal(source) {
|
|
54915
55405
|
const raw = source?.amountReceived;
|
|
54916
55406
|
if (raw === null || raw === void 0 || raw === "") {
|
|
@@ -55238,7 +55728,8 @@ function classifyStatus({
|
|
|
55238
55728
|
if (!bitrefill && (routerStatus === "paid" || coinbase?.settled === true)) {
|
|
55239
55729
|
return mk("settled", "Coinbase invoice settled by the funder wallet.", { terminal: true });
|
|
55240
55730
|
}
|
|
55241
|
-
|
|
55731
|
+
const nativeAccepted = isNativeSource(source.chainId, source.tokenSymbol) && NATIVE_PROGRESS_STATUSES.has(payment?.status);
|
|
55732
|
+
if (moneyDetected && receipt && receipt.state === "underpaid" && !nativeAccepted) {
|
|
55242
55733
|
return mk(
|
|
55243
55734
|
"underpaid",
|
|
55244
55735
|
"Less arrived than the order requires. Do NOT send a top-up to the same address \u2014 escalate.",
|
|
@@ -55379,6 +55870,24 @@ async function main(argv) {
|
|
|
55379
55870
|
const quote = await quoteInvoice({ url: String(url) });
|
|
55380
55871
|
const snapshot2 = snapshotFromQuote(quote);
|
|
55381
55872
|
const payability = derivePayable(snapshot2, now);
|
|
55873
|
+
const nativeOffered = Object.values(NATIVE_COINS).map((c2) => ({
|
|
55874
|
+
chainId: c2.chainId,
|
|
55875
|
+
tokenSymbol: c2.symbol,
|
|
55876
|
+
chain: chainName(c2.chainId),
|
|
55877
|
+
offer: nativeOfferFor({
|
|
55878
|
+
chainId: c2.chainId,
|
|
55879
|
+
tokenSymbol: c2.symbol,
|
|
55880
|
+
supportedSources: quote?.supportedSources,
|
|
55881
|
+
nativeMinUsd: quote?.nativeMinUsd,
|
|
55882
|
+
callerPaysUsd: snapshot2.callerPays ?? snapshot2.original
|
|
55883
|
+
})
|
|
55884
|
+
})).filter((c2) => c2.offer.ok).map((c2) => ({ chainId: c2.chainId, tokenSymbol: c2.tokenSymbol, chain: c2.chain, minUsd: c2.offer.minUsd }));
|
|
55885
|
+
const nativeRequested = chosenSource && isNativeSource(chosenSource.chainId, chosenSource.tokenSymbol) ? nativeOfferFor({
|
|
55886
|
+
...chosenSource,
|
|
55887
|
+
supportedSources: quote?.supportedSources,
|
|
55888
|
+
nativeMinUsd: quote?.nativeMinUsd,
|
|
55889
|
+
callerPaysUsd: snapshot2.callerPays ?? snapshot2.original
|
|
55890
|
+
}) : null;
|
|
55382
55891
|
const payload = {
|
|
55383
55892
|
success: payability.payable,
|
|
55384
55893
|
step: "quote",
|
|
@@ -55397,6 +55906,11 @@ async function main(argv) {
|
|
|
55397
55906
|
coinbaseExpiryIso: payability.expiryMs ? new Date(payability.expiryMs).toISOString() : null,
|
|
55398
55907
|
chosenSource,
|
|
55399
55908
|
supportedSources: SUPPORTED_SOURCES,
|
|
55909
|
+
// The router's own per-invoice list ({ chainId: [symbols] }), verbatim,
|
|
55910
|
+
// and the native coins it makes payable for this invoice.
|
|
55911
|
+
routerSupportedSources: quote?.supportedSources && typeof quote.supportedSources === "object" ? quote.supportedSources : null,
|
|
55912
|
+
nativeOffered,
|
|
55913
|
+
nativeNote: "Native coins are exact-out: the coin amount is fixed at order creation and its price is locked only until quoteExpiresAt. Up to $2,000 per invoice; native ETH on Ethereum needs $1.",
|
|
55400
55914
|
quoteReceipt: quote?.quoteReceipt ?? null,
|
|
55401
55915
|
quoteReceiptTtlSeconds: 60,
|
|
55402
55916
|
quoteReceiptNote: "Short-lived (~60s). create-order.js takes its own fresh quote; do not carry this over.",
|
|
@@ -55407,6 +55921,12 @@ async function main(argv) {
|
|
|
55407
55921
|
payload.error = { code: payability.code, message: payability.reason };
|
|
55408
55922
|
emit(payload, EXIT_ERROR);
|
|
55409
55923
|
}
|
|
55924
|
+
if (nativeRequested && !nativeRequested.ok) {
|
|
55925
|
+
payload.success = false;
|
|
55926
|
+
payload.nextStep = null;
|
|
55927
|
+
payload.error = { code: nativeRequested.code, message: nativeRequested.reason };
|
|
55928
|
+
emit(payload, EXIT_ERROR);
|
|
55929
|
+
}
|
|
55410
55930
|
if (snapshot2.callerPays && snapshot2.original && normalizeDecimal(snapshot2.callerPays) !== normalizeDecimal(snapshot2.original)) {
|
|
55411
55931
|
payload.warnings = [
|
|
55412
55932
|
`callerPays (${snapshot2.callerPays}) differs from the invoice amount (${snapshot2.original}). This flow is supposed to charge the full invoice \u2014 do not proceed until that is explained.`
|
|
@@ -55458,6 +55978,28 @@ async function main2(argv) {
|
|
|
55458
55978
|
const quote = await quoteInvoice({ url: String(url) });
|
|
55459
55979
|
const snapshot2 = snapshotFromQuote(quote);
|
|
55460
55980
|
const quoteReceipt = quote?.quoteReceipt ?? null;
|
|
55981
|
+
const native = isNativeSource(chainId, tokenSymbol);
|
|
55982
|
+
if (native) {
|
|
55983
|
+
const offer = nativeOfferFor({
|
|
55984
|
+
chainId,
|
|
55985
|
+
tokenSymbol,
|
|
55986
|
+
supportedSources: quote?.supportedSources,
|
|
55987
|
+
nativeMinUsd: quote?.nativeMinUsd,
|
|
55988
|
+
callerPaysUsd: snapshot2.callerPays ?? snapshot2.original
|
|
55989
|
+
});
|
|
55990
|
+
if (!offer.ok) {
|
|
55991
|
+
emit(
|
|
55992
|
+
{
|
|
55993
|
+
success: false,
|
|
55994
|
+
step: "native-offer",
|
|
55995
|
+
error: { code: offer.code, message: offer.reason },
|
|
55996
|
+
linkId: snapshot2.linkId ?? parsedLinkId,
|
|
55997
|
+
guidance: "Nothing was created. Choose USDC or USDT, or another coin the quote lists."
|
|
55998
|
+
},
|
|
55999
|
+
EXIT_ERROR
|
|
56000
|
+
);
|
|
56001
|
+
}
|
|
56002
|
+
}
|
|
55461
56003
|
const created = await createInvoice({
|
|
55462
56004
|
url: String(url),
|
|
55463
56005
|
source: requested,
|
|
@@ -55544,6 +56086,17 @@ async function main2(argv) {
|
|
|
55544
56086
|
}
|
|
55545
56087
|
const lightning = String(source.chainId) === "lightning";
|
|
55546
56088
|
const bolt11 = source.lnInvoice ?? payment?.lnInvoice ?? null;
|
|
56089
|
+
let prior = null;
|
|
56090
|
+
try {
|
|
56091
|
+
prior = native ? readState(rozoPaymentId) : null;
|
|
56092
|
+
} catch {
|
|
56093
|
+
prior = null;
|
|
56094
|
+
}
|
|
56095
|
+
const quoteExpiresAt = priceLockFor({
|
|
56096
|
+
native,
|
|
56097
|
+
payment,
|
|
56098
|
+
others: [created?.quoteExpiresAt, prior?.quoteExpiresAt, prior?.confirmation?.quoteExpiresAt]
|
|
56099
|
+
});
|
|
55547
56100
|
const expiry = checkExpiry({
|
|
55548
56101
|
now: Date.now(),
|
|
55549
56102
|
chainId: source.chainId ?? chainId,
|
|
@@ -55552,7 +56105,8 @@ async function main2(argv) {
|
|
|
55552
56105
|
// For Lightning the BOLT11's own validity is an extra gate. We only have a
|
|
55553
56106
|
// separate expiry if the backend exposes one; otherwise the intent expiry
|
|
55554
56107
|
// governs and we still require the 10-minute floor via the margin.
|
|
55555
|
-
...lightning ? { bolt11ExpiresAt: payment?.expiresAt } : {}
|
|
56108
|
+
...lightning ? { bolt11ExpiresAt: payment?.expiresAt } : {},
|
|
56109
|
+
...native ? { quoteExpiresAt } : {}
|
|
55556
56110
|
});
|
|
55557
56111
|
if (!expiry.ok) {
|
|
55558
56112
|
emit(
|
|
@@ -55562,7 +56116,7 @@ async function main2(argv) {
|
|
|
55562
56116
|
error: { code: expiry.code, message: expiry.reason, details: expiry },
|
|
55563
56117
|
linkId: created.linkId ?? parsedLinkId,
|
|
55564
56118
|
rozoPaymentId,
|
|
55565
|
-
guidance: "Not enough time remains to fund, bridge and settle safely. Ask the merchant for a fresh link and start over. Do not fund this order."
|
|
56119
|
+
guidance: String(expiry.code).startsWith("QUOTE_") ? "The coin price lock for this order has run out, or is about to. Do not fund it. An unfunded order costs nothing; once it has expired, run pay again for a fresh price." : "Not enough time remains to fund, bridge and settle safely. Ask the merchant for a fresh link and start over. Do not fund this order."
|
|
55566
56120
|
},
|
|
55567
56121
|
EXIT_ERROR
|
|
55568
56122
|
);
|
|
@@ -55617,14 +56171,20 @@ async function main2(argv) {
|
|
|
55617
56171
|
receiverMemo: source.receiverMemo ?? null,
|
|
55618
56172
|
amount: source.amount,
|
|
55619
56173
|
amountUnit: source.amountUnit ?? null,
|
|
55620
|
-
expiresAt: payment?.expiresAt ?? null
|
|
56174
|
+
expiresAt: payment?.expiresAt ?? null,
|
|
56175
|
+
...native ? { quoteExpiresAt } : {}
|
|
55621
56176
|
});
|
|
55622
56177
|
const usd = created.original ?? snapshot2.original;
|
|
55623
56178
|
const family = chainFamily(source.chainId);
|
|
55624
56179
|
const tier = confirmTier(usd);
|
|
55625
56180
|
const depositInfo = guard.deposit;
|
|
55626
56181
|
if (confirmed) {
|
|
55627
|
-
recordConfirmation(rozoPaymentId, {
|
|
56182
|
+
recordConfirmation(rozoPaymentId, {
|
|
56183
|
+
source,
|
|
56184
|
+
invoiceAmount: usd,
|
|
56185
|
+
tier,
|
|
56186
|
+
...native ? { quoteExpiresAt } : {}
|
|
56187
|
+
});
|
|
55628
56188
|
}
|
|
55629
56189
|
const memoRequirement = lightning ? "Lightning invoices carry their own routing data; there is no separate memo." : source.receiverMemo ? "This deposit REQUIRES the memo/tag below. Sending without it will very likely lose the funds." : family === "stellar" ? "A Stellar deposit always requires a memo." : "This deposit does not use a memo. Leave the memo field empty.";
|
|
55630
56190
|
emit({
|
|
@@ -55667,7 +56227,12 @@ async function main2(argv) {
|
|
|
55667
56227
|
lnInvoice: bolt11 || null,
|
|
55668
56228
|
payTo: depositInfo.payTo,
|
|
55669
56229
|
expiresAt: payment?.expiresAt ?? null,
|
|
55670
|
-
expiresIn: formatRemaining(expiry.msRemaining)
|
|
56230
|
+
expiresIn: formatRemaining(expiry.msRemaining),
|
|
56231
|
+
// Native coins are exact-out like Lightning: this exact coin amount,
|
|
56232
|
+
// at a price locked only until quoteExpiresAt.
|
|
56233
|
+
native,
|
|
56234
|
+
exactOut: native || lightning,
|
|
56235
|
+
quoteExpiresAt: native ? quoteExpiresAt : null
|
|
55671
56236
|
} : null,
|
|
55672
56237
|
depositWithheld: !confirmed,
|
|
55673
56238
|
// Safe for prose / chat.
|
|
@@ -55680,11 +56245,16 @@ async function main2(argv) {
|
|
|
55680
56245
|
receiverMemoMasked: maskMemo(source.receiverMemo),
|
|
55681
56246
|
hasMemo: Boolean(source.receiverMemo),
|
|
55682
56247
|
memoType: source.receiverMemo ? STELLAR_MEMO_TYPE : null,
|
|
55683
|
-
memoRequirement
|
|
56248
|
+
memoRequirement,
|
|
56249
|
+
native,
|
|
56250
|
+
priceLockedUntil: native ? quoteExpiresAt : null,
|
|
56251
|
+
// The bare decimal amount (not secret), for balance comparisons.
|
|
56252
|
+
coinAmount: isSatsUnit(source.amountUnit) ? null : String(source.amount ?? "")
|
|
55684
56253
|
},
|
|
55685
56254
|
expiry: {
|
|
55686
56255
|
intentExpiresAt: payment?.expiresAt ?? null,
|
|
55687
56256
|
coinbaseExpiry: snapshot2?.coinbase?.preApprovalExpiry ?? null,
|
|
56257
|
+
quoteExpiresAt: native ? quoteExpiresAt : null,
|
|
55688
56258
|
effectiveDeadlineIso: new Date(expiry.effectiveDeadlineMs).toISOString(),
|
|
55689
56259
|
// A duration, not just a timestamp: this is what a payer actually needs.
|
|
55690
56260
|
expiresIn: formatRemaining(expiry.msRemaining),
|
|
@@ -55700,7 +56270,8 @@ async function main2(argv) {
|
|
|
55700
56270
|
"Wrong token, wrong network, or wrong amount is usually unrecoverable.",
|
|
55701
56271
|
memoRequirement,
|
|
55702
56272
|
"Send exactly once. A second send to the same one-time address is not guaranteed to be credited.",
|
|
55703
|
-
"The deposit amount can exceed the invoice: it includes the bridge and network fees."
|
|
56273
|
+
"The deposit amount can exceed the invoice: it includes the bridge and network fees.",
|
|
56274
|
+
...native ? nativeDepositWarnings({ tokenSymbol: source.tokenSymbol, chainId: source.chainId }) : []
|
|
55704
56275
|
]
|
|
55705
56276
|
},
|
|
55706
56277
|
blacklist: {
|
|
@@ -55910,6 +56481,12 @@ async function main3(argv) {
|
|
|
55910
56481
|
supported: SUPPORTED_SOURCES
|
|
55911
56482
|
});
|
|
55912
56483
|
}
|
|
56484
|
+
if (isNativeSource(chainId, tokenSymbol)) {
|
|
56485
|
+
throw new SkillError(
|
|
56486
|
+
"NATIVE_NOT_AVAILABLE",
|
|
56487
|
+
`${tokenSymbol} on ${chainName(chainId)} is a native coin, and native coins are not available for Bitrefill invoices. Pay with USDC, USDT or BTC over Lightning.`
|
|
56488
|
+
);
|
|
56489
|
+
}
|
|
55913
56490
|
const requested = { chainId, tokenSymbol };
|
|
55914
56491
|
const confirmed = Boolean(args.confirm);
|
|
55915
56492
|
const email = contactEmailFromArgs(args);
|
|
@@ -56380,7 +56957,7 @@ function localSendFor(id, read = readState) {
|
|
|
56380
56957
|
if (!send || !send.status) return null;
|
|
56381
56958
|
return { status: send.status, txHash: publicHash(send.txHash ?? null), claimedAt: send.claimedAt ?? null };
|
|
56382
56959
|
}
|
|
56383
|
-
function sendWindowFor({ provider, chainId, payment, status, bitrefillExpiry, now = Date.now() }) {
|
|
56960
|
+
function sendWindowFor({ provider, chainId, payment, status, bitrefillExpiry, quoteExpiresAt, now = Date.now() }) {
|
|
56384
56961
|
if (provider === "bitrefill") {
|
|
56385
56962
|
const deadline = bitrefillExpiry ?? null;
|
|
56386
56963
|
const expiry2 = checkExpiry({
|
|
@@ -56400,7 +56977,9 @@ function sendWindowFor({ provider, chainId, payment, status, bitrefillExpiry, no
|
|
|
56400
56977
|
now,
|
|
56401
56978
|
chainId,
|
|
56402
56979
|
intentExpiresAt: payment?.expiresAt ?? status?.rozoPayment?.expiresAt,
|
|
56403
|
-
coinbaseExpiry: status?.coinbase?.preApprovalExpiry
|
|
56980
|
+
coinbaseExpiry: status?.coinbase?.preApprovalExpiry,
|
|
56981
|
+
// Native orders: the price lock is a deadline too (undefined otherwise).
|
|
56982
|
+
...quoteExpiresAt !== void 0 ? { quoteExpiresAt } : {}
|
|
56404
56983
|
});
|
|
56405
56984
|
return expiry.ok ? { ok: true, code: null, minutesOfSlack: Math.floor(expiry.msOfSlack / 6e4), deadlineMs: expiry.effectiveDeadlineMs } : { ok: false, code: expiry.code, reason: expiry.reason };
|
|
56406
56985
|
}
|
|
@@ -56454,6 +57033,18 @@ async function snapshot({ rozoPaymentId, linkId, provider: explicitProvider }) {
|
|
|
56454
57033
|
provider
|
|
56455
57034
|
});
|
|
56456
57035
|
const source = payment?.source || status?.rozoPayment?.source || {};
|
|
57036
|
+
const native = isNativeSource(source.chainId, source.tokenSymbol);
|
|
57037
|
+
let localState = null;
|
|
57038
|
+
try {
|
|
57039
|
+
localState = id && isRozoPaymentId(id) ? readState(id) : null;
|
|
57040
|
+
} catch {
|
|
57041
|
+
localState = null;
|
|
57042
|
+
}
|
|
57043
|
+
const quoteExpiresAt = priceLockFor({
|
|
57044
|
+
native,
|
|
57045
|
+
payment: payment || status?.rozoPayment || null,
|
|
57046
|
+
others: [localState?.confirmation?.quoteExpiresAt, localState?.quoteExpiresAt]
|
|
57047
|
+
});
|
|
56457
57048
|
let bitrefillExpiry = null;
|
|
56458
57049
|
let state = verdict.state;
|
|
56459
57050
|
let terminal = verdict.terminal;
|
|
@@ -56513,10 +57104,17 @@ async function snapshot({ rozoPaymentId, linkId, provider: explicitProvider }) {
|
|
|
56513
57104
|
const iso = provider === "bitrefill" ? bitrefillExpiry : payment?.expiresAt ?? status?.rozoPayment?.expiresAt ?? null;
|
|
56514
57105
|
if (!iso) return { expiresAt: null, expiresIn: null, msRemaining: null };
|
|
56515
57106
|
const ms = Date.parse(iso) - Date.now();
|
|
57107
|
+
const lockMs = quoteExpiresAt ? Date.parse(quoteExpiresAt) - Date.now() : NaN;
|
|
56516
57108
|
return {
|
|
56517
57109
|
expiresAt: iso,
|
|
56518
57110
|
expiresIn: formatRemaining(ms),
|
|
56519
|
-
msRemaining: Number.isFinite(ms) ? ms : null
|
|
57111
|
+
msRemaining: Number.isFinite(ms) ? ms : null,
|
|
57112
|
+
// Native orders: the order stays open after the price lock, but a
|
|
57113
|
+
// payment after it is valued at the arrival price. Pay before this.
|
|
57114
|
+
...native ? {
|
|
57115
|
+
quoteExpiresAt: quoteExpiresAt ?? null,
|
|
57116
|
+
priceLockExpiresIn: Number.isFinite(lockMs) ? formatRemaining(lockMs) : null
|
|
57117
|
+
} : {}
|
|
56520
57118
|
};
|
|
56521
57119
|
})(),
|
|
56522
57120
|
payout: {
|
|
@@ -56524,7 +57122,7 @@ async function snapshot({ rozoPaymentId, linkId, provider: explicitProvider }) {
|
|
|
56524
57122
|
confirmedAt: payment?.destination?.confirmedAt ?? status?.rozoPayment?.destination?.confirmedAt ?? null
|
|
56525
57123
|
},
|
|
56526
57124
|
localSend: localSendFor(id),
|
|
56527
|
-
sendWindow: state === "awaiting_deposit" ? sendWindowFor({ provider, chainId: source.chainId, payment, status, bitrefillExpiry }) : null,
|
|
57125
|
+
sendWindow: state === "awaiting_deposit" ? sendWindowFor({ provider, chainId: source.chainId, payment, status, bitrefillExpiry, quoteExpiresAt }) : null,
|
|
56528
57126
|
errors: [statusError, paymentError].filter(Boolean)
|
|
56529
57127
|
};
|
|
56530
57128
|
}
|
|
@@ -56553,6 +57151,9 @@ function watchTimeoutMs(timeoutArg, result, now = Date.now()) {
|
|
|
56553
57151
|
if (result?.payin?.chain === chainName("lightning")) {
|
|
56554
57152
|
return lightningWatchMs(result?.expiry?.expiresAt, { now, fallbackMs: DEFAULT_WATCH_MS });
|
|
56555
57153
|
}
|
|
57154
|
+
if (result?.expiry?.quoteExpiresAt) {
|
|
57155
|
+
return lightningWatchMs(result.expiry.quoteExpiresAt, { now, fallbackMs: DEFAULT_WATCH_MS });
|
|
57156
|
+
}
|
|
56556
57157
|
return DEFAULT_WATCH_MS;
|
|
56557
57158
|
}
|
|
56558
57159
|
async function main4(argv) {
|
|
@@ -56779,11 +57380,14 @@ async function main6(argv) {
|
|
|
56779
57380
|
EXIT_ERROR
|
|
56780
57381
|
);
|
|
56781
57382
|
}
|
|
57383
|
+
const native = isNativeSource(source.chainId, source.tokenSymbol);
|
|
57384
|
+
const quoteExpiresAt = priceLockFor({ native, payment, others: [snap.expiry?.quoteExpiresAt] });
|
|
56782
57385
|
const finalWindow = checkExpiry({
|
|
56783
57386
|
now: Date.now(),
|
|
56784
57387
|
chainId: source.chainId,
|
|
56785
57388
|
intentExpiresAt: payment?.expiresAt ?? snap.sendWindow?.deadlineMs,
|
|
56786
|
-
coinbaseExpiry: snap.sendWindow?.deadlineMs
|
|
57389
|
+
coinbaseExpiry: snap.sendWindow?.deadlineMs,
|
|
57390
|
+
...native ? { quoteExpiresAt } : {}
|
|
56787
57391
|
});
|
|
56788
57392
|
if (!finalWindow.ok) {
|
|
56789
57393
|
emit(
|
|
@@ -56824,7 +57428,7 @@ async function main6(argv) {
|
|
|
56824
57428
|
}
|
|
56825
57429
|
}
|
|
56826
57430
|
const expiresAt = payment?.expiresAt ?? snap.expiry?.expiresAt ?? null;
|
|
56827
|
-
const msRemaining =
|
|
57431
|
+
const msRemaining = Number.isFinite(finalWindow.effectiveDeadlineMs) ? finalWindow.effectiveDeadlineMs - Date.now() : NaN;
|
|
56828
57432
|
const expiresIn = Number.isFinite(msRemaining) ? formatRemaining(msRemaining) : null;
|
|
56829
57433
|
const paymentLink = payment?.paymentLink ?? localPaymentLink(id);
|
|
56830
57434
|
const bolt11 = source.lnInvoice ?? payment?.lnInvoice ?? null;
|
|
@@ -56856,7 +57460,10 @@ async function main6(argv) {
|
|
|
56856
57460
|
lnInvoice: bolt11 || null,
|
|
56857
57461
|
payTo: guard.deposit.payTo,
|
|
56858
57462
|
expiresAt,
|
|
56859
|
-
expiresIn
|
|
57463
|
+
expiresIn,
|
|
57464
|
+
native,
|
|
57465
|
+
exactOut: native || lightning,
|
|
57466
|
+
quoteExpiresAt: native ? quoteExpiresAt : null
|
|
56860
57467
|
} : null,
|
|
56861
57468
|
depositWithheld: !confirmed,
|
|
56862
57469
|
display: {
|
|
@@ -56867,9 +57474,16 @@ async function main6(argv) {
|
|
|
56867
57474
|
payToMasked: maskAddress2(guard.deposit.payTo),
|
|
56868
57475
|
receiverMemoMasked: maskMemo(source.receiverMemo),
|
|
56869
57476
|
hasMemo: Boolean(source.receiverMemo),
|
|
56870
|
-
memoType: source.receiverMemo ? STELLAR_MEMO_TYPE : null
|
|
57477
|
+
memoType: source.receiverMemo ? STELLAR_MEMO_TYPE : null,
|
|
57478
|
+
native,
|
|
57479
|
+
priceLockedUntil: native ? quoteExpiresAt : null
|
|
57480
|
+
},
|
|
57481
|
+
expiry: {
|
|
57482
|
+
expiresAt,
|
|
57483
|
+
expiresIn,
|
|
57484
|
+
...native ? { quoteExpiresAt } : {},
|
|
57485
|
+
minutesOfSlack: snap.sendWindow?.minutesOfSlack ?? null
|
|
56871
57486
|
},
|
|
56872
|
-
expiry: { expiresAt, expiresIn, minutesOfSlack: snap.sendWindow?.minutesOfSlack ?? null },
|
|
56873
57487
|
note: confirmed ? "Send exactly once, exactly this amount, on this chain. Then: rozo-checkout status <id> --watch" : "Deposit address withheld. Confirm the chain, token and amount with the payer, then re-run with --confirm, or open paymentLink."
|
|
56874
57488
|
});
|
|
56875
57489
|
}
|
|
@@ -56934,6 +57548,14 @@ function assertBitrefillLive(state, payment) {
|
|
|
56934
57548
|
if (!expiry.ok) throw new SkillError(expiry.code, expiry.reason, expiry);
|
|
56935
57549
|
return expiry;
|
|
56936
57550
|
}
|
|
57551
|
+
function sendPriceLock(payment, state) {
|
|
57552
|
+
const source = payment?.source || {};
|
|
57553
|
+
return priceLockFor({
|
|
57554
|
+
native: isNativeSource(source.chainId, source.tokenSymbol),
|
|
57555
|
+
payment,
|
|
57556
|
+
others: [state?.confirmation?.quoteExpiresAt, state?.quoteExpiresAt]
|
|
57557
|
+
});
|
|
57558
|
+
}
|
|
56937
57559
|
async function preflight({
|
|
56938
57560
|
rozoPaymentId,
|
|
56939
57561
|
expectFamily,
|
|
@@ -57022,14 +57644,19 @@ async function preflight({
|
|
|
57022
57644
|
let statusNow = null;
|
|
57023
57645
|
let expiry;
|
|
57024
57646
|
if (state.provider === "bitrefill") {
|
|
57647
|
+
if (isNativeSource(source.chainId, source.tokenSymbol)) {
|
|
57648
|
+
throw new SkillError("NATIVE_NOT_AVAILABLE", "Native coins are not available for Bitrefill invoices.");
|
|
57649
|
+
}
|
|
57025
57650
|
expiry = assertBitrefillLive(state, payment);
|
|
57026
57651
|
} else {
|
|
57027
57652
|
statusNow = await invoiceStatus({ linkId: state.linkId });
|
|
57653
|
+
const quoteExpiresAt = sendPriceLock(payment, state);
|
|
57028
57654
|
expiry = checkExpiry({
|
|
57029
57655
|
now: Date.now(),
|
|
57030
57656
|
chainId: source.chainId,
|
|
57031
57657
|
intentExpiresAt: payment?.expiresAt,
|
|
57032
|
-
coinbaseExpiry: statusNow?.coinbase?.preApprovalExpiry
|
|
57658
|
+
coinbaseExpiry: statusNow?.coinbase?.preApprovalExpiry,
|
|
57659
|
+
...quoteExpiresAt !== void 0 ? { quoteExpiresAt } : {}
|
|
57033
57660
|
});
|
|
57034
57661
|
if (!expiry.ok) throw new SkillError(expiry.code, expiry.reason, expiry);
|
|
57035
57662
|
const payable = checkPayable(statusNow, Date.now());
|
|
@@ -57050,11 +57677,22 @@ async function preflight({
|
|
|
57050
57677
|
blacklist,
|
|
57051
57678
|
amountAtomic: deposit.amountAtomic,
|
|
57052
57679
|
deposit,
|
|
57053
|
-
statusNow
|
|
57680
|
+
statusNow,
|
|
57681
|
+
quoteExpiresAt: sendPriceLock(payment, state)
|
|
57054
57682
|
};
|
|
57055
57683
|
}
|
|
57056
|
-
async function finalPayabilityCheck({
|
|
57684
|
+
async function finalPayabilityCheck({
|
|
57685
|
+
linkId,
|
|
57686
|
+
chainId,
|
|
57687
|
+
intentExpiresAt,
|
|
57688
|
+
quoteExpiresAt = void 0,
|
|
57689
|
+
state = null,
|
|
57690
|
+
rozoPaymentId = null
|
|
57691
|
+
}) {
|
|
57057
57692
|
if (state?.provider === "bitrefill") {
|
|
57693
|
+
if (isNativeSource(state?.source?.chainId, state?.source?.tokenSymbol)) {
|
|
57694
|
+
throw new SkillError("NATIVE_NOT_AVAILABLE", "Native coins are not available for Bitrefill invoices.");
|
|
57695
|
+
}
|
|
57058
57696
|
const id = rozoPaymentId ?? state.rozoPaymentId;
|
|
57059
57697
|
const payment = await getPayment(id);
|
|
57060
57698
|
const guard = reuseGuard({ payment, requested: state.source });
|
|
@@ -57071,7 +57709,9 @@ async function finalPayabilityCheck({ linkId, chainId, intentExpiresAt, state =
|
|
|
57071
57709
|
now: Date.now(),
|
|
57072
57710
|
chainId,
|
|
57073
57711
|
intentExpiresAt,
|
|
57074
|
-
coinbaseExpiry: statusNow?.coinbase?.preApprovalExpiry
|
|
57712
|
+
coinbaseExpiry: statusNow?.coinbase?.preApprovalExpiry,
|
|
57713
|
+
// Native orders: the price lock, re-checked as the very last gate too.
|
|
57714
|
+
...quoteExpiresAt !== void 0 ? { quoteExpiresAt } : {}
|
|
57075
57715
|
});
|
|
57076
57716
|
if (!expiry.ok) throw new SkillError(expiry.code, expiry.reason, expiry);
|
|
57077
57717
|
return { statusNow, payable, expiry };
|
|
@@ -57116,165 +57756,146 @@ function broadcastOutcome({ receiptStatus, executionError = null, receiptSeen =
|
|
|
57116
57756
|
};
|
|
57117
57757
|
}
|
|
57118
57758
|
|
|
57119
|
-
// scripts/src/lib/
|
|
57120
|
-
var
|
|
57121
|
-
|
|
57122
|
-
|
|
57123
|
-
|
|
57124
|
-
|
|
57125
|
-
|
|
57126
|
-
|
|
57127
|
-
|
|
57128
|
-
|
|
57129
|
-
|
|
57130
|
-
if (raw === void 0 || raw === "") return DEFAULT_GAS_BUFFER_PCT;
|
|
57131
|
-
const n = Number(raw);
|
|
57132
|
-
if (!Number.isInteger(n) || n < 0 || n > MAX_GAS_BUFFER_PCT) return DEFAULT_GAS_BUFFER_PCT;
|
|
57133
|
-
return n;
|
|
57134
|
-
}
|
|
57135
|
-
function formatAtomic(atomic, decimals) {
|
|
57136
|
-
const neg = atomic < 0n;
|
|
57137
|
-
const v = neg ? -atomic : atomic;
|
|
57138
|
-
const base = 10n ** BigInt(decimals);
|
|
57139
|
-
const whole = v / base;
|
|
57140
|
-
const frac = (v % base).toString().padStart(decimals, "0").replace(/0+$/, "");
|
|
57141
|
-
return `${neg ? "-" : ""}${whole}${frac ? `.${frac}` : ""}`;
|
|
57142
|
-
}
|
|
57143
|
-
function evmFeeRequirement({ gasEstimate, maxFeePerGas, gasPrice, bufferPct = DEFAULT_GAS_BUFFER_PCT }) {
|
|
57144
|
-
const perGas = typeof maxFeePerGas === "bigint" ? maxFeePerGas : typeof gasPrice === "bigint" ? gasPrice : null;
|
|
57145
|
-
if (typeof gasEstimate !== "bigint" || perGas === null) return null;
|
|
57146
|
-
const gasLimit = (gasEstimate * BigInt(100 + bufferPct) + 99n) / 100n;
|
|
57147
|
-
return { gasLimit, perGas, pricing: typeof maxFeePerGas === "bigint" ? "eip1559" : "legacy", fee: gasLimit * perGas };
|
|
57148
|
-
}
|
|
57149
|
-
function assessFee({ balance, required, decimals, symbol, network }) {
|
|
57150
|
-
const ok = required === null ? balance > 0n : balance >= required;
|
|
57151
|
-
const details = {
|
|
57152
|
-
network,
|
|
57153
|
-
feeCoin: symbol,
|
|
57154
|
-
balance: formatAtomic(balance, decimals),
|
|
57155
|
-
required: required === null ? null : formatAtomic(required, decimals),
|
|
57156
|
-
shortfall: required === null || ok ? null : formatAtomic(required - balance, decimals)
|
|
57157
|
-
};
|
|
57158
|
-
return { ok, details };
|
|
57159
|
-
}
|
|
57160
|
-
function insufficient(details, extra) {
|
|
57161
|
-
const need = details.required ? `about ${details.required} ${details.feeCoin}` : `some ${details.feeCoin}`;
|
|
57162
|
-
return new SkillError(
|
|
57163
|
-
"INSUFFICIENT_GAS",
|
|
57164
|
-
`This wallet holds ${details.balance} ${details.feeCoin} on ${details.network} but needs ${need} for the network fee${details.shortfall ? ` (short by ${details.shortfall} ${details.feeCoin})` : ""}. Nothing was signed. Add ${details.feeCoin} on ${details.network} to this wallet and re-run, or pay with a different coin.` + (extra ? ` ${extra}` : ""),
|
|
57165
|
-
details
|
|
57166
|
-
);
|
|
57167
|
-
}
|
|
57168
|
-
function unavailable(network, err) {
|
|
57169
|
-
return new SkillError(
|
|
57170
|
-
"GAS_CHECK_UNAVAILABLE",
|
|
57171
|
-
`Could not check the network fee on ${network}: ${redact(err?.shortMessage || err?.message || "unknown error")}. This is not evidence of a shortfall. Nothing was signed. Retry, pass --rpc <url>, or pay by hand from your wallet.`,
|
|
57172
|
-
{ network }
|
|
57173
|
-
);
|
|
57759
|
+
// scripts/src/lib/native-send.mjs
|
|
57760
|
+
var import_web3 = __toESM(require_index_cjs(), 1);
|
|
57761
|
+
var MEMO_PROGRAM_ID = new import_web3.PublicKey("MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr");
|
|
57762
|
+
var EVM_ADDRESS_RE2 = /^0x[0-9a-fA-F]{40}$/;
|
|
57763
|
+
function assertNativeTokenAddress(tokenAddress) {
|
|
57764
|
+
if (!isNativeTokenAddress(tokenAddress)) {
|
|
57765
|
+
throw new SkillError(
|
|
57766
|
+
"NATIVE_TOKEN_ADDRESS_UNEXPECTED",
|
|
57767
|
+
"This native coin order names a token contract or mint, which a native payment never uses. Refusing to guess which asset to send."
|
|
57768
|
+
);
|
|
57769
|
+
}
|
|
57174
57770
|
}
|
|
57175
|
-
|
|
57176
|
-
|
|
57177
|
-
|
|
57178
|
-
} catch (err) {
|
|
57179
|
-
if (err?.name !== "Eip1559FeesNotSupportedError") throw err;
|
|
57180
|
-
return client.estimateFeesPerGas({ type: "legacy" });
|
|
57771
|
+
function assertPositive(amountAtomic) {
|
|
57772
|
+
if (typeof amountAtomic !== "bigint" || amountAtomic <= 0n) {
|
|
57773
|
+
throw new SkillError("DEPOSIT_INCOMPLETE", "The order carries no positive native amount.");
|
|
57181
57774
|
}
|
|
57182
57775
|
}
|
|
57183
|
-
|
|
57184
|
-
var OP_STACK_CHAIN_IDS = /* @__PURE__ */ new Set([8453]);
|
|
57185
|
-
async function evmGasPrecheck({
|
|
57776
|
+
async function prepareEvmNativeSend({
|
|
57186
57777
|
client,
|
|
57187
57778
|
chainId,
|
|
57188
57779
|
from: from15,
|
|
57189
57780
|
to,
|
|
57190
|
-
|
|
57191
|
-
|
|
57192
|
-
|
|
57781
|
+
amountAtomic,
|
|
57782
|
+
tokenAddress,
|
|
57783
|
+
tokenSymbol,
|
|
57193
57784
|
estimateL1Fee: estimateL1Fee2 = null
|
|
57194
57785
|
}) {
|
|
57195
|
-
|
|
57786
|
+
assertNativeTokenAddress(tokenAddress);
|
|
57787
|
+
assertPositive(amountAtomic);
|
|
57788
|
+
if (!EVM_ADDRESS_RE2.test(String(to ?? ""))) {
|
|
57789
|
+
throw new SkillError("BAD_DEPOSIT_ADDRESS", "The deposit address is not a valid EVM address.");
|
|
57790
|
+
}
|
|
57196
57791
|
let balance;
|
|
57197
57792
|
try {
|
|
57198
57793
|
balance = await client.getBalance({ address: from15 });
|
|
57199
57794
|
} catch (err) {
|
|
57200
|
-
throw
|
|
57795
|
+
throw new SkillError(
|
|
57796
|
+
"GAS_CHECK_UNAVAILABLE",
|
|
57797
|
+
`Could not read the ${tokenSymbol} balance: ${redact(err?.shortMessage || err?.message || "unknown error")}. This is not evidence of a shortfall. Nothing was signed.`
|
|
57798
|
+
);
|
|
57201
57799
|
}
|
|
57202
|
-
|
|
57203
|
-
|
|
57204
|
-
|
|
57205
|
-
|
|
57206
|
-
|
|
57207
|
-
} catch (err) {
|
|
57208
|
-
if (balance === 0n) {
|
|
57209
|
-
throw insufficient(
|
|
57210
|
-
assessFee({ balance, required: null, decimals: 18, symbol: coin.symbol, network: coin.network }).details
|
|
57211
|
-
);
|
|
57212
|
-
}
|
|
57213
|
-
throw unavailable(coin.network, err);
|
|
57800
|
+
if (balance < amountAtomic) {
|
|
57801
|
+
throw new SkillError(
|
|
57802
|
+
"INSUFFICIENT_BALANCE",
|
|
57803
|
+
`This wallet holds ${formatAtomic(balance, 18)} ${tokenSymbol}; the order needs exactly ${formatAtomic(amountAtomic, 18)} ${tokenSymbol} plus the network fee. Nothing was signed.`
|
|
57804
|
+
);
|
|
57214
57805
|
}
|
|
57215
|
-
const
|
|
57216
|
-
|
|
57217
|
-
|
|
57218
|
-
|
|
57219
|
-
|
|
57806
|
+
const networkFee = await evmGasPrecheck({
|
|
57807
|
+
client,
|
|
57808
|
+
chainId,
|
|
57809
|
+
from: from15,
|
|
57810
|
+
to,
|
|
57811
|
+
data: void 0,
|
|
57812
|
+
value: amountAtomic,
|
|
57813
|
+
estimateL1Fee: estimateL1Fee2
|
|
57220
57814
|
});
|
|
57221
|
-
|
|
57222
|
-
|
|
57223
|
-
|
|
57224
|
-
|
|
57225
|
-
|
|
57226
|
-
|
|
57227
|
-
|
|
57228
|
-
l1Fee = (await estimateL1Fee2() * BigInt(100 + bufferPct) + 99n) / 100n;
|
|
57229
|
-
} catch (err) {
|
|
57230
|
-
throw unavailable(coin.network, err);
|
|
57231
|
-
}
|
|
57815
|
+
return { request: { to, value: amountAtomic }, balance, networkFee };
|
|
57816
|
+
}
|
|
57817
|
+
function assertPreparedNativeRequest(prepared, { to, value }) {
|
|
57818
|
+
const gotTo = String(prepared?.to ?? "").toLowerCase();
|
|
57819
|
+
const data = prepared?.data;
|
|
57820
|
+
if (gotTo !== String(to).toLowerCase()) {
|
|
57821
|
+
throw new SkillError("PREPARED_TX_MISMATCH", "The prepared transaction is not addressed to the deposit address.");
|
|
57232
57822
|
}
|
|
57233
|
-
|
|
57234
|
-
|
|
57235
|
-
|
|
57236
|
-
|
|
57237
|
-
|
|
57238
|
-
|
|
57239
|
-
|
|
57240
|
-
l1DataFee: OP_STACK_CHAIN_IDS.has(Number(chainId)) ? formatAtomic(l1Fee, 18) : null
|
|
57241
|
-
};
|
|
57242
|
-
if (!ok) throw insufficient(full);
|
|
57243
|
-
return full;
|
|
57823
|
+
if (prepared?.value !== value) {
|
|
57824
|
+
throw new SkillError("PREPARED_TX_MISMATCH", "The prepared transaction does not carry the exact order amount.");
|
|
57825
|
+
}
|
|
57826
|
+
if (data !== void 0 && data !== null && data !== "0x" && data !== "") {
|
|
57827
|
+
throw new SkillError("PREPARED_TX_MISMATCH", "A native payment must not carry calldata.");
|
|
57828
|
+
}
|
|
57829
|
+
return true;
|
|
57244
57830
|
}
|
|
57245
|
-
|
|
57246
|
-
|
|
57247
|
-
|
|
57248
|
-
|
|
57249
|
-
|
|
57831
|
+
async function prepareSolNativeSend({
|
|
57832
|
+
connection,
|
|
57833
|
+
payer,
|
|
57834
|
+
recipientAddress,
|
|
57835
|
+
amountAtomic,
|
|
57836
|
+
memo = null,
|
|
57837
|
+
tokenAddress
|
|
57838
|
+
}) {
|
|
57839
|
+
assertNativeTokenAddress(tokenAddress);
|
|
57840
|
+
assertPositive(amountAtomic);
|
|
57841
|
+
let recipient;
|
|
57842
|
+
try {
|
|
57843
|
+
recipient = new import_web3.PublicKey(recipientAddress);
|
|
57844
|
+
} catch {
|
|
57845
|
+
throw new SkillError("BAD_DEPOSIT_ADDRESS", "The deposit address is not a valid Solana address.");
|
|
57846
|
+
}
|
|
57847
|
+
let info;
|
|
57250
57848
|
let rentMin;
|
|
57849
|
+
let balance;
|
|
57251
57850
|
try {
|
|
57252
|
-
|
|
57253
|
-
const res = await connection.getFeeForMessage(message, "confirmed");
|
|
57254
|
-
if (res?.value === null || res?.value === void 0) {
|
|
57255
|
-
throw new Error("the node returned no fee for this transaction (stale blockhash?)");
|
|
57256
|
-
}
|
|
57257
|
-
fee = BigInt(res.value);
|
|
57851
|
+
info = await connection.getAccountInfo(recipient, "confirmed");
|
|
57258
57852
|
rentMin = BigInt(await connection.getMinimumBalanceForRentExemption(0));
|
|
57853
|
+
balance = BigInt(await connection.getBalance(payer, "confirmed"));
|
|
57259
57854
|
} catch (err) {
|
|
57260
|
-
|
|
57261
|
-
|
|
57262
|
-
|
|
57263
|
-
|
|
57264
|
-
}
|
|
57265
|
-
throw unavailable(network, err);
|
|
57855
|
+
throw new SkillError(
|
|
57856
|
+
"RPC_READ_FAILED",
|
|
57857
|
+
`Could not read the Solana accounts: ${redact(err?.message || "unknown error")}. Nothing was signed.`
|
|
57858
|
+
);
|
|
57266
57859
|
}
|
|
57267
|
-
|
|
57268
|
-
|
|
57269
|
-
|
|
57270
|
-
|
|
57271
|
-
if (!ok) {
|
|
57272
|
-
throw insufficient(
|
|
57273
|
-
full,
|
|
57274
|
-
balance >= fee ? "Solana also requires a wallet to keep a small minimum balance after paying the fee." : null
|
|
57860
|
+
if (info && (info.executable || !info.owner?.equals?.(import_web3.SystemProgram.programId))) {
|
|
57861
|
+
throw new SkillError(
|
|
57862
|
+
"DEPOSIT_ACCOUNT_NOT_WALLET",
|
|
57863
|
+
"The deposit address is not a plain Solana wallet (it is a token account or a program). Refusing to send SOL to it."
|
|
57275
57864
|
);
|
|
57276
57865
|
}
|
|
57277
|
-
|
|
57866
|
+
if (!info && amountAtomic < rentMin) {
|
|
57867
|
+
throw new SkillError(
|
|
57868
|
+
"DEPOSIT_BELOW_RENT",
|
|
57869
|
+
`The deposit address does not exist yet and ${formatAtomic(amountAtomic, 9)} SOL is below the ${formatAtomic(rentMin, 9)} SOL needed to open it. Pay this order another way.`
|
|
57870
|
+
);
|
|
57871
|
+
}
|
|
57872
|
+
if (balance < amountAtomic) {
|
|
57873
|
+
throw new SkillError(
|
|
57874
|
+
"INSUFFICIENT_BALANCE",
|
|
57875
|
+
`This wallet holds ${formatAtomic(balance, 9)} SOL; the order needs exactly ${formatAtomic(amountAtomic, 9)} SOL plus the network fee. Nothing was signed.`
|
|
57876
|
+
);
|
|
57877
|
+
}
|
|
57878
|
+
const tx = new import_web3.Transaction();
|
|
57879
|
+
tx.add(import_web3.SystemProgram.transfer({ fromPubkey: payer, toPubkey: recipient, lamports: amountAtomic }));
|
|
57880
|
+
if (memo) {
|
|
57881
|
+
tx.add(
|
|
57882
|
+
new import_web3.TransactionInstruction({
|
|
57883
|
+
keys: [],
|
|
57884
|
+
programId: MEMO_PROGRAM_ID,
|
|
57885
|
+
data: Buffer.from(String(memo), "utf8")
|
|
57886
|
+
})
|
|
57887
|
+
);
|
|
57888
|
+
}
|
|
57889
|
+
const { blockhash, lastValidBlockHeight } = await connection.getLatestBlockhash("confirmed");
|
|
57890
|
+
tx.recentBlockhash = blockhash;
|
|
57891
|
+
tx.feePayer = payer;
|
|
57892
|
+
const networkFee = await solFeePrecheck({
|
|
57893
|
+
connection,
|
|
57894
|
+
payer,
|
|
57895
|
+
message: tx.compileMessage(),
|
|
57896
|
+
value: amountAtomic
|
|
57897
|
+
});
|
|
57898
|
+
return { tx, recipient, blockhash, lastValidBlockHeight, networkFee, recipientExists: Boolean(info) };
|
|
57278
57899
|
}
|
|
57279
57900
|
|
|
57280
57901
|
// node_modules/viem/_esm/op-stack/contracts.js
|
|
@@ -57566,30 +58187,15 @@ var ERC20_TRANSFER_ABI = [
|
|
|
57566
58187
|
outputs: [{ name: "", type: "uint8" }]
|
|
57567
58188
|
}
|
|
57568
58189
|
];
|
|
57569
|
-
var DEFAULT_RPC = {
|
|
57570
|
-
1: "https://eth.llamarpc.com",
|
|
57571
|
-
56: "https://bsc-dataseed.binance.org",
|
|
57572
|
-
137: "https://polygon-rpc.com",
|
|
57573
|
-
8453: "https://mainnet.base.org"
|
|
57574
|
-
};
|
|
57575
|
-
function rpcFor(chainId, override) {
|
|
57576
|
-
if (override && override !== true) return String(override);
|
|
57577
|
-
const env = process.env[`ROZO_CHECKOUT_RPC_${chainId}`];
|
|
57578
|
-
if (env) return env;
|
|
57579
|
-
const fallback = DEFAULT_RPC[String(chainId)];
|
|
57580
|
-
if (!fallback) {
|
|
57581
|
-
throw new SkillError(
|
|
57582
|
-
"NO_RPC",
|
|
57583
|
-
`No RPC known for chain ${chainId}. Pass --rpc <url> or set ROZO_CHECKOUT_RPC_${chainId}.`
|
|
57584
|
-
);
|
|
57585
|
-
}
|
|
57586
|
-
return fallback;
|
|
57587
|
-
}
|
|
57588
58190
|
function chainDef(chainId, rpcUrl) {
|
|
57589
58191
|
return defineChain({
|
|
57590
58192
|
id: Number(chainId),
|
|
57591
58193
|
name: chainName(chainId),
|
|
57592
|
-
nativeCurrency: {
|
|
58194
|
+
nativeCurrency: {
|
|
58195
|
+
name: EVM_FEE_COIN[Number(chainId)]?.symbol ?? "Native",
|
|
58196
|
+
symbol: EVM_FEE_COIN[Number(chainId)]?.symbol ?? "NATIVE",
|
|
58197
|
+
decimals: 18
|
|
58198
|
+
},
|
|
57593
58199
|
rpcUrls: { default: { http: [rpcUrl] } }
|
|
57594
58200
|
});
|
|
57595
58201
|
}
|
|
@@ -57608,7 +58214,7 @@ async function main7(argv) {
|
|
|
57608
58214
|
const sender = account.address;
|
|
57609
58215
|
const keySource = loaded.label;
|
|
57610
58216
|
const dryRun = Boolean(args["dry-run"]);
|
|
57611
|
-
const { source, state, expiry, amountAtomic, payment } = await preflight({
|
|
58217
|
+
const { source, state, expiry, amountAtomic, payment, quoteExpiresAt } = await preflight({
|
|
57612
58218
|
rozoPaymentId,
|
|
57613
58219
|
expectFamily: "evm",
|
|
57614
58220
|
senderAddress: sender,
|
|
@@ -57616,8 +58222,9 @@ async function main7(argv) {
|
|
|
57616
58222
|
dryRun
|
|
57617
58223
|
});
|
|
57618
58224
|
const chainId = Number(source.chainId);
|
|
58225
|
+
const native = isNativeSource(source.chainId, source.tokenSymbol);
|
|
57619
58226
|
const tokenAddress = source.tokenAddress;
|
|
57620
|
-
if (!tokenAddress || !/^0x[0-9a-fA-F]{40}$/.test(tokenAddress)) {
|
|
58227
|
+
if (!native && (!tokenAddress || !/^0x[0-9a-fA-F]{40}$/.test(tokenAddress))) {
|
|
57621
58228
|
throw new SkillError("NO_TOKEN_ADDRESS", "The order did not carry a usable ERC-20 address.");
|
|
57622
58229
|
}
|
|
57623
58230
|
const to = source.receiverAddress;
|
|
@@ -57639,57 +58246,75 @@ async function main7(argv) {
|
|
|
57639
58246
|
`RPC reports chain ${rpcChainId} but this order settles on ${chainId}. Refusing to sign.`
|
|
57640
58247
|
);
|
|
57641
58248
|
}
|
|
57642
|
-
|
|
57643
|
-
|
|
57644
|
-
|
|
57645
|
-
|
|
57646
|
-
|
|
57647
|
-
}
|
|
57648
|
-
|
|
57649
|
-
|
|
57650
|
-
|
|
57651
|
-
|
|
57652
|
-
|
|
57653
|
-
|
|
57654
|
-
|
|
57655
|
-
|
|
57656
|
-
|
|
57657
|
-
|
|
57658
|
-
|
|
57659
|
-
|
|
57660
|
-
|
|
58249
|
+
const l1FeeFor = (tx) => OP_STACK_CHAIN_IDS.has(chainId) ? () => estimateL1Fee(pub, {
|
|
58250
|
+
account: sender,
|
|
58251
|
+
...tx,
|
|
58252
|
+
chain,
|
|
58253
|
+
gasPriceOracleAddress: OP_STACK_GAS_PRICE_ORACLE
|
|
58254
|
+
}) : null;
|
|
58255
|
+
let txRequest;
|
|
58256
|
+
let networkFee;
|
|
58257
|
+
if (native) {
|
|
58258
|
+
const prepared = await prepareEvmNativeSend({
|
|
58259
|
+
client: pub,
|
|
58260
|
+
chainId,
|
|
58261
|
+
from: sender,
|
|
58262
|
+
to,
|
|
58263
|
+
amountAtomic,
|
|
58264
|
+
tokenAddress,
|
|
58265
|
+
tokenSymbol: source.tokenSymbol,
|
|
58266
|
+
estimateL1Fee: l1FeeFor({ to, value: amountAtomic })
|
|
58267
|
+
});
|
|
58268
|
+
txRequest = prepared.request;
|
|
58269
|
+
networkFee = prepared.networkFee;
|
|
58270
|
+
} else {
|
|
58271
|
+
let onChainDecimals;
|
|
58272
|
+
try {
|
|
58273
|
+
onChainDecimals = Number(
|
|
58274
|
+
await pub.readContract({ address: tokenAddress, abi: ERC20_TRANSFER_ABI, functionName: "decimals" })
|
|
58275
|
+
);
|
|
58276
|
+
} catch (err) {
|
|
58277
|
+
throw new SkillError("TOKEN_READ_FAILED", `Could not read token decimals: ${redact(err?.message)}`);
|
|
58278
|
+
}
|
|
58279
|
+
const expectedDecimals = decimalsFor(source.chainId, source.tokenSymbol);
|
|
58280
|
+
if (onChainDecimals !== expectedDecimals) {
|
|
58281
|
+
throw new SkillError(
|
|
58282
|
+
"DECIMALS_MISMATCH",
|
|
58283
|
+
`Token reports ${onChainDecimals} decimals but ${source.tokenSymbol} on ${chainName(chainId)} is expected to have ${expectedDecimals}. Refusing to sign an amount that could be off by orders of magnitude.`
|
|
58284
|
+
);
|
|
58285
|
+
}
|
|
58286
|
+
let balance;
|
|
58287
|
+
try {
|
|
58288
|
+
balance = await pub.readContract({
|
|
58289
|
+
address: tokenAddress,
|
|
58290
|
+
abi: ERC20_TRANSFER_ABI,
|
|
58291
|
+
functionName: "balanceOf",
|
|
58292
|
+
args: [sender]
|
|
58293
|
+
});
|
|
58294
|
+
} catch (err) {
|
|
58295
|
+
throw new SkillError("TOKEN_READ_FAILED", `Could not read balance: ${redact(err?.message)}`);
|
|
58296
|
+
}
|
|
58297
|
+
if (balance < amountAtomic) {
|
|
58298
|
+
throw new SkillError(
|
|
58299
|
+
"INSUFFICIENT_BALANCE",
|
|
58300
|
+
`Sender holds ${balance} atomic units of ${source.tokenSymbol} on ${chainName(chainId)}; ${amountAtomic} are required.`
|
|
58301
|
+
);
|
|
58302
|
+
}
|
|
58303
|
+
const data = encodeFunctionData({
|
|
57661
58304
|
abi: ERC20_TRANSFER_ABI,
|
|
57662
|
-
functionName: "
|
|
57663
|
-
args: [
|
|
58305
|
+
functionName: "transfer",
|
|
58306
|
+
args: [to, amountAtomic]
|
|
57664
58307
|
});
|
|
57665
|
-
|
|
57666
|
-
|
|
57667
|
-
|
|
57668
|
-
|
|
57669
|
-
throw new SkillError(
|
|
57670
|
-
"INSUFFICIENT_BALANCE",
|
|
57671
|
-
`Sender holds ${balance} atomic units of ${source.tokenSymbol} on ${chainName(chainId)}; ${amountAtomic} are required.`
|
|
57672
|
-
);
|
|
57673
|
-
}
|
|
57674
|
-
const data = encodeFunctionData({
|
|
57675
|
-
abi: ERC20_TRANSFER_ABI,
|
|
57676
|
-
functionName: "transfer",
|
|
57677
|
-
args: [to, amountAtomic]
|
|
57678
|
-
});
|
|
57679
|
-
const networkFee = await evmGasPrecheck({
|
|
57680
|
-
client: pub,
|
|
57681
|
-
chainId,
|
|
57682
|
-
from: sender,
|
|
57683
|
-
to: tokenAddress,
|
|
57684
|
-
data,
|
|
57685
|
-
estimateL1Fee: OP_STACK_CHAIN_IDS.has(chainId) ? () => estimateL1Fee(pub, {
|
|
57686
|
-
account: sender,
|
|
58308
|
+
networkFee = await evmGasPrecheck({
|
|
58309
|
+
client: pub,
|
|
58310
|
+
chainId,
|
|
58311
|
+
from: sender,
|
|
57687
58312
|
to: tokenAddress,
|
|
57688
58313
|
data,
|
|
57689
|
-
|
|
57690
|
-
|
|
57691
|
-
|
|
57692
|
-
}
|
|
58314
|
+
estimateL1Fee: l1FeeFor({ to: tokenAddress, data })
|
|
58315
|
+
});
|
|
58316
|
+
txRequest = { to: tokenAddress, data, value: 0n };
|
|
58317
|
+
}
|
|
57693
58318
|
if (dryRun) {
|
|
57694
58319
|
emit({
|
|
57695
58320
|
success: true,
|
|
@@ -57700,6 +58325,9 @@ async function main7(argv) {
|
|
|
57700
58325
|
chainId,
|
|
57701
58326
|
chain: chainName(chainId),
|
|
57702
58327
|
tokenSymbol: source.tokenSymbol,
|
|
58328
|
+
native,
|
|
58329
|
+
kind: native ? "native value transfer" : "ERC-20 transfer",
|
|
58330
|
+
priceLockedUntil: native ? quoteExpiresAt : null,
|
|
57703
58331
|
amountAtomic: amountAtomic.toString(),
|
|
57704
58332
|
amount: source.amount,
|
|
57705
58333
|
toMasked: maskAddress2(to),
|
|
@@ -57715,11 +58343,8 @@ async function main7(argv) {
|
|
|
57715
58343
|
});
|
|
57716
58344
|
}
|
|
57717
58345
|
const wallet = createWalletClient({ account, chain, transport: http(rpcUrl) });
|
|
57718
|
-
const request2 = await wallet.prepareTransactionRequest(
|
|
57719
|
-
|
|
57720
|
-
data,
|
|
57721
|
-
value: 0n
|
|
57722
|
-
});
|
|
58346
|
+
const request2 = await wallet.prepareTransactionRequest(txRequest);
|
|
58347
|
+
if (native) assertPreparedNativeRequest(request2, { to, value: amountAtomic });
|
|
57723
58348
|
const serialized = await wallet.signTransaction(request2);
|
|
57724
58349
|
const expectedTxHash = keccak256(serialized);
|
|
57725
58350
|
const nonceBefore = Number(request2.nonce);
|
|
@@ -57727,6 +58352,7 @@ async function main7(argv) {
|
|
|
57727
58352
|
linkId: state.linkId,
|
|
57728
58353
|
chainId: source.chainId,
|
|
57729
58354
|
intentExpiresAt: payment?.expiresAt,
|
|
58355
|
+
quoteExpiresAt,
|
|
57730
58356
|
state,
|
|
57731
58357
|
rozoPaymentId
|
|
57732
58358
|
});
|
|
@@ -57735,6 +58361,7 @@ async function main7(argv) {
|
|
|
57735
58361
|
{
|
|
57736
58362
|
chainId: String(chainId),
|
|
57737
58363
|
tokenSymbol: source.tokenSymbol,
|
|
58364
|
+
native,
|
|
57738
58365
|
from: sender,
|
|
57739
58366
|
to,
|
|
57740
58367
|
amountAtomic: amountAtomic.toString(),
|
|
@@ -57841,18 +58468,18 @@ async function run7(argv = process.argv.slice(2)) {
|
|
|
57841
58468
|
}
|
|
57842
58469
|
|
|
57843
58470
|
// scripts/src/send-sol.mjs
|
|
57844
|
-
var
|
|
58471
|
+
var import_web33 = __toESM(require_index_cjs(), 1);
|
|
57845
58472
|
|
|
57846
58473
|
// scripts/src/spl-lite.mjs
|
|
57847
|
-
var
|
|
57848
|
-
var TOKEN_PROGRAM_ID = new
|
|
57849
|
-
var ASSOCIATED_TOKEN_PROGRAM_ID = new
|
|
58474
|
+
var import_web32 = __toESM(require_index_cjs(), 1);
|
|
58475
|
+
var TOKEN_PROGRAM_ID = new import_web32.PublicKey("TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA");
|
|
58476
|
+
var ASSOCIATED_TOKEN_PROGRAM_ID = new import_web32.PublicKey(
|
|
57850
58477
|
"ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL"
|
|
57851
58478
|
);
|
|
57852
58479
|
var TOKEN_ACCOUNT_LEN = 165;
|
|
57853
58480
|
var MINT_LEN = 82;
|
|
57854
58481
|
async function getAssociatedTokenAddress(mint, owner) {
|
|
57855
|
-
const [address] =
|
|
58482
|
+
const [address] = import_web32.PublicKey.findProgramAddressSync(
|
|
57856
58483
|
[owner.toBuffer(), TOKEN_PROGRAM_ID.toBuffer(), mint.toBuffer()],
|
|
57857
58484
|
ASSOCIATED_TOKEN_PROGRAM_ID
|
|
57858
58485
|
);
|
|
@@ -57873,8 +58500,8 @@ async function getAccount(connection, address) {
|
|
|
57873
58500
|
const data = await fetchOwnedAccount(connection, address, TOKEN_ACCOUNT_LEN, "Token account");
|
|
57874
58501
|
return {
|
|
57875
58502
|
address,
|
|
57876
|
-
mint: new
|
|
57877
|
-
owner: new
|
|
58503
|
+
mint: new import_web32.PublicKey(data.subarray(0, 32)),
|
|
58504
|
+
owner: new import_web32.PublicKey(data.subarray(32, 64)),
|
|
57878
58505
|
amount: data.readBigUInt64LE(64)
|
|
57879
58506
|
};
|
|
57880
58507
|
}
|
|
@@ -57891,7 +58518,7 @@ function createTransferCheckedInstruction(source, mint, destination, owner, amou
|
|
|
57891
58518
|
data.writeUInt8(12, 0);
|
|
57892
58519
|
data.writeBigUInt64LE(BigInt(amount), 1);
|
|
57893
58520
|
data.writeUInt8(decimals, 9);
|
|
57894
|
-
return new
|
|
58521
|
+
return new import_web32.TransactionInstruction({
|
|
57895
58522
|
programId: TOKEN_PROGRAM_ID,
|
|
57896
58523
|
keys: [
|
|
57897
58524
|
{ pubkey: source, isSigner: false, isWritable: true },
|
|
@@ -57904,7 +58531,6 @@ function createTransferCheckedInstruction(source, mint, destination, owner, amou
|
|
|
57904
58531
|
}
|
|
57905
58532
|
|
|
57906
58533
|
// scripts/src/send-sol.mjs
|
|
57907
|
-
var MEMO_PROGRAM_ID = new import_web32.PublicKey("MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr");
|
|
57908
58534
|
var MAINNET_GENESIS = "5eykt4UsFv8P8NJdTREpY1vzqKqZKvdpKuc147dw2N9d";
|
|
57909
58535
|
var B58_ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
|
|
57910
58536
|
async function main8(argv) {
|
|
@@ -57919,19 +58545,19 @@ async function main8(argv) {
|
|
|
57919
58545
|
});
|
|
57920
58546
|
const loaded = await loadKeySource(plan, { family: "solana", askPassphrase: promptPassphrase });
|
|
57921
58547
|
const secret = loaded.secretKey;
|
|
57922
|
-
const keypair = secret.length === 64 ?
|
|
58548
|
+
const keypair = secret.length === 64 ? import_web33.Keypair.fromSecretKey(secret) : import_web33.Keypair.fromSeed(secret);
|
|
57923
58549
|
const sender = keypair.publicKey.toBase58();
|
|
57924
58550
|
const keySource = loaded.label;
|
|
57925
58551
|
const dryRun = Boolean(args["dry-run"]);
|
|
57926
|
-
const { source, state, expiry, amountAtomic, payment } = await preflight({
|
|
58552
|
+
const { source, state, expiry, amountAtomic, payment, quoteExpiresAt } = await preflight({
|
|
57927
58553
|
rozoPaymentId,
|
|
57928
58554
|
expectFamily: "solana",
|
|
57929
58555
|
senderAddress: sender,
|
|
57930
58556
|
send: Boolean(args.send),
|
|
57931
58557
|
dryRun
|
|
57932
58558
|
});
|
|
57933
|
-
const rpcUrl =
|
|
57934
|
-
const connection = new
|
|
58559
|
+
const rpcUrl = rpcFor("900", args.rpc);
|
|
58560
|
+
const connection = new import_web33.Connection(rpcUrl, "confirmed");
|
|
57935
58561
|
let genesis;
|
|
57936
58562
|
try {
|
|
57937
58563
|
genesis = await connection.getGenesisHash();
|
|
@@ -57944,94 +58570,111 @@ async function main8(argv) {
|
|
|
57944
58570
|
"The configured Solana RPC is not mainnet-beta. Refusing to sign."
|
|
57945
58571
|
);
|
|
57946
58572
|
}
|
|
57947
|
-
|
|
57948
|
-
|
|
57949
|
-
|
|
57950
|
-
|
|
57951
|
-
|
|
57952
|
-
}
|
|
57953
|
-
let recipient;
|
|
57954
|
-
try {
|
|
57955
|
-
recipient = new import_web32.PublicKey(source.receiverAddress);
|
|
57956
|
-
} catch {
|
|
57957
|
-
throw new SkillError("BAD_DEPOSIT_ADDRESS", "The deposit address is not a valid Solana address.");
|
|
57958
|
-
}
|
|
57959
|
-
const mintInfo = await getMint(connection, mint);
|
|
57960
|
-
const expectedDecimals = decimalsFor(source.chainId, source.tokenSymbol);
|
|
57961
|
-
if (mintInfo.decimals !== expectedDecimals) {
|
|
57962
|
-
throw new SkillError(
|
|
57963
|
-
"DECIMALS_MISMATCH",
|
|
57964
|
-
`Mint reports ${mintInfo.decimals} decimals, expected ${expectedDecimals} for ${source.tokenSymbol} on Solana. Refusing to sign.`
|
|
57965
|
-
);
|
|
57966
|
-
}
|
|
57967
|
-
const fromAta = await getAssociatedTokenAddress(mint, keypair.publicKey);
|
|
57968
|
-
let fromAccount;
|
|
57969
|
-
try {
|
|
57970
|
-
fromAccount = await getAccount(connection, fromAta);
|
|
57971
|
-
} catch {
|
|
57972
|
-
throw new SkillError(
|
|
57973
|
-
"NO_TOKEN_ACCOUNT",
|
|
57974
|
-
`The sender has no ${source.tokenSymbol} token account on Solana.`
|
|
57975
|
-
);
|
|
57976
|
-
}
|
|
57977
|
-
if (fromAccount.amount < amountAtomic) {
|
|
57978
|
-
throw new SkillError(
|
|
57979
|
-
"INSUFFICIENT_BALANCE",
|
|
57980
|
-
`Sender holds ${fromAccount.amount} atomic units; ${amountAtomic} are required.`
|
|
57981
|
-
);
|
|
57982
|
-
}
|
|
57983
|
-
let toAta;
|
|
58573
|
+
const native = isNativeSource(source.chainId, source.tokenSymbol);
|
|
58574
|
+
let tx;
|
|
58575
|
+
let blockhash;
|
|
58576
|
+
let lastValidBlockHeight;
|
|
58577
|
+
let networkFee;
|
|
57984
58578
|
let toIsTokenAccount = false;
|
|
57985
|
-
|
|
57986
|
-
const
|
|
57987
|
-
|
|
58579
|
+
if (native) {
|
|
58580
|
+
const prepared = await prepareSolNativeSend({
|
|
58581
|
+
connection,
|
|
58582
|
+
payer: keypair.publicKey,
|
|
58583
|
+
recipientAddress: source.receiverAddress,
|
|
58584
|
+
amountAtomic,
|
|
58585
|
+
memo: source.receiverMemo ?? null,
|
|
58586
|
+
tokenAddress: source.tokenAddress
|
|
58587
|
+
});
|
|
58588
|
+
({ tx, blockhash, lastValidBlockHeight, networkFee } = prepared);
|
|
58589
|
+
} else {
|
|
58590
|
+
let mint;
|
|
58591
|
+
try {
|
|
58592
|
+
mint = new import_web33.PublicKey(source.tokenAddress);
|
|
58593
|
+
} catch {
|
|
58594
|
+
throw new SkillError("NO_TOKEN_ADDRESS", "The order did not carry a usable SPL mint address.");
|
|
58595
|
+
}
|
|
58596
|
+
let recipient;
|
|
58597
|
+
try {
|
|
58598
|
+
recipient = new import_web33.PublicKey(source.receiverAddress);
|
|
58599
|
+
} catch {
|
|
58600
|
+
throw new SkillError("BAD_DEPOSIT_ADDRESS", "The deposit address is not a valid Solana address.");
|
|
58601
|
+
}
|
|
58602
|
+
const mintInfo = await getMint(connection, mint);
|
|
58603
|
+
const expectedDecimals = decimalsFor(source.chainId, source.tokenSymbol);
|
|
58604
|
+
if (mintInfo.decimals !== expectedDecimals) {
|
|
57988
58605
|
throw new SkillError(
|
|
57989
|
-
"
|
|
57990
|
-
|
|
58606
|
+
"DECIMALS_MISMATCH",
|
|
58607
|
+
`Mint reports ${mintInfo.decimals} decimals, expected ${expectedDecimals} for ${source.tokenSymbol} on Solana. Refusing to sign.`
|
|
57991
58608
|
);
|
|
57992
58609
|
}
|
|
57993
|
-
|
|
57994
|
-
|
|
57995
|
-
} catch (err) {
|
|
57996
|
-
if (err instanceof SkillError) throw err;
|
|
57997
|
-
toAta = await getAssociatedTokenAddress(mint, recipient);
|
|
58610
|
+
const fromAta = await getAssociatedTokenAddress(mint, keypair.publicKey);
|
|
58611
|
+
let fromAccount;
|
|
57998
58612
|
try {
|
|
57999
|
-
await getAccount(connection,
|
|
58613
|
+
fromAccount = await getAccount(connection, fromAta);
|
|
58000
58614
|
} catch {
|
|
58001
58615
|
throw new SkillError(
|
|
58002
|
-
"
|
|
58003
|
-
|
|
58616
|
+
"NO_TOKEN_ACCOUNT",
|
|
58617
|
+
`The sender has no ${source.tokenSymbol} token account on Solana.`
|
|
58004
58618
|
);
|
|
58005
58619
|
}
|
|
58006
|
-
|
|
58007
|
-
|
|
58008
|
-
|
|
58009
|
-
|
|
58010
|
-
|
|
58011
|
-
|
|
58012
|
-
|
|
58013
|
-
|
|
58014
|
-
|
|
58015
|
-
|
|
58016
|
-
|
|
58017
|
-
|
|
58018
|
-
|
|
58620
|
+
if (fromAccount.amount < amountAtomic) {
|
|
58621
|
+
throw new SkillError(
|
|
58622
|
+
"INSUFFICIENT_BALANCE",
|
|
58623
|
+
`Sender holds ${fromAccount.amount} atomic units; ${amountAtomic} are required.`
|
|
58624
|
+
);
|
|
58625
|
+
}
|
|
58626
|
+
let toAta;
|
|
58627
|
+
try {
|
|
58628
|
+
const acc = await getAccount(connection, recipient);
|
|
58629
|
+
if (acc.mint.toBase58() !== mint.toBase58()) {
|
|
58630
|
+
throw new SkillError(
|
|
58631
|
+
"DEPOSIT_ACCOUNT_MISMATCH",
|
|
58632
|
+
"The deposit token account is for a different mint. Refusing to send."
|
|
58633
|
+
);
|
|
58634
|
+
}
|
|
58635
|
+
toAta = recipient;
|
|
58636
|
+
toIsTokenAccount = true;
|
|
58637
|
+
} catch (err) {
|
|
58638
|
+
if (err instanceof SkillError) throw err;
|
|
58639
|
+
toAta = await getAssociatedTokenAddress(mint, recipient);
|
|
58640
|
+
try {
|
|
58641
|
+
await getAccount(connection, toAta);
|
|
58642
|
+
} catch {
|
|
58643
|
+
throw new SkillError(
|
|
58644
|
+
"DEPOSIT_ACCOUNT_MISSING",
|
|
58645
|
+
"The deposit address has no token account for this mint. Refusing to create one on its behalf \u2014 re-run create-order.js for fresh instructions."
|
|
58646
|
+
);
|
|
58647
|
+
}
|
|
58648
|
+
}
|
|
58649
|
+
tx = new import_web33.Transaction();
|
|
58019
58650
|
tx.add(
|
|
58020
|
-
|
|
58021
|
-
|
|
58022
|
-
|
|
58023
|
-
|
|
58024
|
-
|
|
58651
|
+
createTransferCheckedInstruction(
|
|
58652
|
+
fromAta,
|
|
58653
|
+
mint,
|
|
58654
|
+
toAta,
|
|
58655
|
+
keypair.publicKey,
|
|
58656
|
+
amountAtomic,
|
|
58657
|
+
mintInfo.decimals
|
|
58658
|
+
)
|
|
58025
58659
|
);
|
|
58660
|
+
if (source.receiverMemo) {
|
|
58661
|
+
tx.add(
|
|
58662
|
+
new import_web33.TransactionInstruction({
|
|
58663
|
+
keys: [],
|
|
58664
|
+
programId: MEMO_PROGRAM_ID,
|
|
58665
|
+
data: Buffer.from(String(source.receiverMemo), "utf8")
|
|
58666
|
+
})
|
|
58667
|
+
);
|
|
58668
|
+
}
|
|
58669
|
+
({ blockhash, lastValidBlockHeight } = await connection.getLatestBlockhash("confirmed"));
|
|
58670
|
+
tx.recentBlockhash = blockhash;
|
|
58671
|
+
tx.feePayer = keypair.publicKey;
|
|
58672
|
+
networkFee = await solFeePrecheck({
|
|
58673
|
+
connection,
|
|
58674
|
+
payer: keypair.publicKey,
|
|
58675
|
+
message: tx.compileMessage()
|
|
58676
|
+
});
|
|
58026
58677
|
}
|
|
58027
|
-
const { blockhash, lastValidBlockHeight } = await connection.getLatestBlockhash("confirmed");
|
|
58028
|
-
tx.recentBlockhash = blockhash;
|
|
58029
|
-
tx.feePayer = keypair.publicKey;
|
|
58030
|
-
const networkFee = await solFeePrecheck({
|
|
58031
|
-
connection,
|
|
58032
|
-
payer: keypair.publicKey,
|
|
58033
|
-
message: tx.compileMessage()
|
|
58034
|
-
});
|
|
58035
58678
|
if (dryRun) {
|
|
58036
58679
|
emit({
|
|
58037
58680
|
success: true,
|
|
@@ -58041,6 +58684,9 @@ async function main8(argv) {
|
|
|
58041
58684
|
wouldSend: {
|
|
58042
58685
|
chain: chainName(900),
|
|
58043
58686
|
tokenSymbol: source.tokenSymbol,
|
|
58687
|
+
native,
|
|
58688
|
+
kind: native ? "native SOL transfer" : "SPL transfer",
|
|
58689
|
+
priceLockedUntil: native ? quoteExpiresAt : null,
|
|
58044
58690
|
amountAtomic: amountAtomic.toString(),
|
|
58045
58691
|
amount: source.amount,
|
|
58046
58692
|
toMasked: maskAddress2(source.receiverAddress),
|
|
@@ -58063,6 +58709,7 @@ async function main8(argv) {
|
|
|
58063
58709
|
linkId: state.linkId,
|
|
58064
58710
|
chainId: source.chainId,
|
|
58065
58711
|
intentExpiresAt: payment?.expiresAt,
|
|
58712
|
+
quoteExpiresAt,
|
|
58066
58713
|
state,
|
|
58067
58714
|
rozoPaymentId
|
|
58068
58715
|
});
|
|
@@ -58071,6 +58718,7 @@ async function main8(argv) {
|
|
|
58071
58718
|
{
|
|
58072
58719
|
chainId: "900",
|
|
58073
58720
|
tokenSymbol: source.tokenSymbol,
|
|
58721
|
+
native,
|
|
58074
58722
|
from: sender,
|
|
58075
58723
|
to: source.receiverAddress,
|
|
58076
58724
|
amountAtomic: amountAtomic.toString(),
|
|
@@ -59073,45 +59721,59 @@ async function askPayerAddress(saved) {
|
|
|
59073
59721
|
const family = vetPayerAddress(address);
|
|
59074
59722
|
return family ? { address, family } : null;
|
|
59075
59723
|
}
|
|
59076
|
-
async function pickSource({ invoiceUsd, saved, fresh }) {
|
|
59724
|
+
async function pickSource({ invoiceUsd, saved, fresh, isOffered }) {
|
|
59077
59725
|
const payer = await askPayerAddress(fresh ? null : saved);
|
|
59078
|
-
|
|
59726
|
+
const options = pickerOptionsFor(isOffered);
|
|
59727
|
+
let marked = options.map((o) => ({ ...o, mark: "unchecked", balanceUsd: null }));
|
|
59079
59728
|
let checked = null;
|
|
59080
59729
|
if (payer) {
|
|
59081
59730
|
out(dim(" Checking balances\u2026"));
|
|
59082
|
-
const result = await
|
|
59083
|
-
|
|
59084
|
-
|
|
59731
|
+
const [result, native] = await Promise.all([
|
|
59732
|
+
fetchWalletOptions({ address: payer.address, usdRequired: invoiceUsd }),
|
|
59733
|
+
payer.family === "evm" || payer.family === "solana" ? fetchNativeBalances({ address: payer.address, family: payer.family, isOffered }) : Promise.resolve([])
|
|
59734
|
+
]);
|
|
59735
|
+
if (result.ok || native.some((n) => n.ok)) {
|
|
59736
|
+
marked = markPickerOptions(options, { ...result, family: payer.family, native });
|
|
59085
59737
|
checked = result;
|
|
59086
|
-
}
|
|
59087
|
-
|
|
59738
|
+
}
|
|
59739
|
+
if (!result.ok) {
|
|
59740
|
+
out(` ${yellow(`Could not check stablecoin balances (${result.reason}).`)}`);
|
|
59088
59741
|
}
|
|
59089
59742
|
}
|
|
59090
59743
|
out();
|
|
59091
59744
|
out(` ${bold("Which coin do you want to pay with?")}`);
|
|
59092
|
-
const
|
|
59745
|
+
const remembered = fresh ? null : saved?.lastPreset ?? null;
|
|
59746
|
+
const savedPreset = options.some((o) => o.preset === remembered) ? remembered : null;
|
|
59093
59747
|
let group = null;
|
|
59094
59748
|
for (const o of marked) {
|
|
59095
|
-
|
|
59096
|
-
|
|
59749
|
+
const heading = o.group ?? o.token;
|
|
59750
|
+
if (heading !== group) {
|
|
59751
|
+
group = heading;
|
|
59097
59752
|
out();
|
|
59098
|
-
out(` ${dim(
|
|
59753
|
+
out(` ${dim(heading)}`);
|
|
59754
|
+
if (heading === "Native coins") {
|
|
59755
|
+
out(` ${dim("exact amount and price set when the order is created; price locked about 1 hour")}`);
|
|
59756
|
+
}
|
|
59099
59757
|
}
|
|
59100
|
-
const badge = o.mark === "affordable" ? green(`\u2713 $${Number(o.balanceUsd ?? 0).toFixed(2)} available`) : o.mark === "insufficient" ? dim("\u2717 insufficient") : dim("\u2014 not checked");
|
|
59758
|
+
const badge = o.mark === "affordable" ? green(`\u2713 $${Number(o.balanceUsd ?? 0).toFixed(2)} available`) : o.mark === "held" ? green(`\u2713 ${o.held} held`) + dim(" (plus gas needed)") : o.mark === "insufficient" ? dim(o.note ? `\u2717 ${o.note}` : "\u2717 insufficient") : dim("\u2014 not checked");
|
|
59101
59759
|
const star = savedPreset === o.preset ? bold(" (last used)") : "";
|
|
59102
|
-
out(` ${String(o.number).padStart(2)}. ${o.chain.padEnd(
|
|
59760
|
+
out(` ${String(o.number).padStart(2)}. ${(o.label ?? o.chain).padEnd(18)} ${badge}${star}`);
|
|
59103
59761
|
}
|
|
59104
59762
|
out();
|
|
59105
59763
|
const defaultChoice = savedPreset ? ` [Enter for ${savedPreset}]` : "";
|
|
59106
59764
|
for (let attempt = 0; attempt < 3; attempt++) {
|
|
59107
|
-
const answer = String(await ask(` Number 1-${
|
|
59765
|
+
const answer = String(await ask(` Number 1-${options.length}${defaultChoice}: `)).trim();
|
|
59108
59766
|
const raw = answer || savedPreset;
|
|
59109
59767
|
if (!raw) {
|
|
59110
59768
|
out(` ${yellow("Type the number of a coin.")}`);
|
|
59111
59769
|
continue;
|
|
59112
59770
|
}
|
|
59113
59771
|
try {
|
|
59114
|
-
const choice = resolvePickerChoice(raw);
|
|
59772
|
+
const choice = resolvePickerChoice(raw, options);
|
|
59773
|
+
if (isNativeSource(choice.chainId, choice.tokenSymbol) && typeof isOffered === "function" && !isOffered(choice.chainId, choice.tokenSymbol)) {
|
|
59774
|
+
out(` ${yellow(`${choice.tokenSymbol} on ${chainName(choice.chainId)} is not offered for this invoice. Choose another coin.`)}`);
|
|
59775
|
+
continue;
|
|
59776
|
+
}
|
|
59115
59777
|
if (checked && isProvablyShort(choice, checked)) {
|
|
59116
59778
|
out(` ${yellow("That wallet appears not to hold enough for this invoice.")}`);
|
|
59117
59779
|
out(` ${dim("You can still choose it \u2014 you may be paying from a different wallet.")}`);
|
|
@@ -59155,6 +59817,10 @@ async function cmdQuote(opts) {
|
|
|
59155
59817
|
out(` Invoice ${bold(`${payload.invoice?.amount} ${payload.invoice?.fiat?.currency ?? "USD"}`)}`);
|
|
59156
59818
|
out(` You pay ${payload.callerPays} ${dim("(no discount on this route)")}`);
|
|
59157
59819
|
out(` Expires ${payload.coinbaseExpiryIso ?? "unknown"}`);
|
|
59820
|
+
const natives = (payload.nativeOffered ?? []).map((n) => presetFor(n.chainId, n.tokenSymbol)).filter(Boolean);
|
|
59821
|
+
if (natives.length) {
|
|
59822
|
+
out(` Native ${natives.join(", ")} ${dim("(exact-out; price locked about 1 hour)")}`);
|
|
59823
|
+
}
|
|
59158
59824
|
out();
|
|
59159
59825
|
out(dim(" Next: rozo-checkout pay <link> --with usdt-solana"));
|
|
59160
59826
|
out();
|
|
@@ -59182,6 +59848,9 @@ async function cmdStatus(opts) {
|
|
|
59182
59848
|
if (payload.expiry?.expiresIn && !payload.terminal) {
|
|
59183
59849
|
out(` Expires in ${payload.expiry.expiresIn}`);
|
|
59184
59850
|
}
|
|
59851
|
+
if (payload.expiry?.priceLockExpiresIn && !payload.terminal && payload.state === "awaiting_deposit") {
|
|
59852
|
+
out(` Price locked for ${payload.expiry.priceLockExpiresIn} ${dim("(native coin: do not send after this)")}`);
|
|
59853
|
+
}
|
|
59185
59854
|
if (payload.payin?.txHash) out(` Pay-in ${payload.payin.txHash}`);
|
|
59186
59855
|
if (payload.guidance) out(` ${payload.escalate ? red(payload.guidance) : dim(payload.guidance)}`);
|
|
59187
59856
|
printMoneyWarning(payload);
|
|
@@ -59240,7 +59909,11 @@ async function cmdResume(opts) {
|
|
|
59240
59909
|
if (payload.display?.hasMemo) {
|
|
59241
59910
|
out(` Memo ${payload.display.receiverMemoMasked} ${dim(`(${payload.display.memoType})`)}`);
|
|
59242
59911
|
}
|
|
59243
|
-
if (payload.
|
|
59912
|
+
if (payload.display?.native) {
|
|
59913
|
+
if (payload.expiry?.expiresIn) out(` Price locked for ${bold(payload.expiry.expiresIn)} more ${dim("(do not send after that)")}`);
|
|
59914
|
+
} else if (payload.expiry?.expiresIn) {
|
|
59915
|
+
out(` Expires in ${bold(payload.expiry.expiresIn)}`);
|
|
59916
|
+
}
|
|
59244
59917
|
if (payload.paymentLink) out(` Pay page ${payload.paymentLink}`);
|
|
59245
59918
|
out();
|
|
59246
59919
|
}
|
|
@@ -59307,6 +59980,7 @@ async function cmdPay(opts) {
|
|
|
59307
59980
|
let chosenPreset = null;
|
|
59308
59981
|
let payer = null;
|
|
59309
59982
|
let invoiceUsd = null;
|
|
59983
|
+
let isOffered = null;
|
|
59310
59984
|
if (opts.bitrefill) {
|
|
59311
59985
|
invoiceUsd = Number(opts.bitrefill.amount);
|
|
59312
59986
|
} else if (!opts.source || opts.payer) {
|
|
@@ -59318,6 +59992,8 @@ async function cmdPay(opts) {
|
|
|
59318
59992
|
return q.exitCode;
|
|
59319
59993
|
}
|
|
59320
59994
|
invoiceUsd = Number(q.payload.invoice?.amount);
|
|
59995
|
+
const offered = new Set((q.payload.nativeOffered ?? []).map((n) => `${n.chainId}:${n.tokenSymbol}`));
|
|
59996
|
+
isOffered = (chainId2, tokenSymbol2) => offered.has(`${chainId2}:${String(tokenSymbol2).toUpperCase()}`);
|
|
59321
59997
|
}
|
|
59322
59998
|
if (!opts.source) {
|
|
59323
59999
|
if (!process.stdin.isTTY || opts.json) {
|
|
@@ -59326,7 +60002,7 @@ async function cmdPay(opts) {
|
|
|
59326
60002
|
"No coin specified. Pass --with (e.g. --with usdt-solana), or run this on a terminal to choose from a list. There is no default."
|
|
59327
60003
|
);
|
|
59328
60004
|
}
|
|
59329
|
-
const picked = await pickSource({ invoiceUsd, saved, fresh: opts.fresh });
|
|
60005
|
+
const picked = await pickSource({ invoiceUsd, saved, fresh: opts.fresh, isOffered });
|
|
59330
60006
|
opts.source = { chainId: picked.chainId, tokenSymbol: picked.tokenSymbol };
|
|
59331
60007
|
chosenPreset = picked.preset;
|
|
59332
60008
|
payer = picked.payer;
|
|
@@ -59336,27 +60012,42 @@ async function cmdPay(opts) {
|
|
|
59336
60012
|
throw new CliError("BAD_PAYER_ADDRESS", "That is not a recognisable EVM, Solana or Stellar address.");
|
|
59337
60013
|
}
|
|
59338
60014
|
assertNotBlacklisted([{ address: opts.payer, family, role: "wallet address" }], loadBlacklist());
|
|
59339
|
-
|
|
59340
|
-
|
|
59341
|
-
throw new SkillErrorLike(
|
|
59342
|
-
"INSUFFICIENT_BALANCE",
|
|
59343
|
-
`${opts.payer.slice(0, 6)}\u2026${opts.payer.slice(-4)} does not appear to hold enough ${opts.source.tokenSymbol} for a $${invoiceUsd} invoice. Choose another coin, or omit --payer to proceed anyway from a different wallet.`
|
|
59344
|
-
);
|
|
59345
|
-
}
|
|
59346
|
-
if (!result.ok && !opts.json) {
|
|
59347
|
-
out(` ${yellow(`Could not check balances (${result.reason}). Continuing.`)}`);
|
|
59348
|
-
} else if (result.ok && !opts.json) {
|
|
59349
|
-
const hit = (result.options ?? []).find(
|
|
59350
|
-
(o) => o.chainId === String(opts.source.chainId) && o.tokenSymbol === String(opts.source.tokenSymbol).toUpperCase()
|
|
59351
|
-
);
|
|
60015
|
+
if (isNativeSource(opts.source.chainId, opts.source.tokenSymbol)) {
|
|
60016
|
+
const n = await fetchNativeBalance({ chainId: opts.source.chainId, address: opts.payer });
|
|
59352
60017
|
const short = `${opts.payer.slice(0, 6)}\u2026${opts.payer.slice(-4)}`;
|
|
59353
|
-
if (
|
|
59354
|
-
|
|
59355
|
-
|
|
59356
|
-
|
|
60018
|
+
if (n.ok && n.balanceAtomic === 0n) {
|
|
60019
|
+
throw new SkillErrorLike(
|
|
60020
|
+
"INSUFFICIENT_BALANCE",
|
|
60021
|
+
`${short} holds no ${opts.source.tokenSymbol} on ${chainName(opts.source.chainId)}. Choose another coin, or omit --payer to proceed anyway from a different wallet.`
|
|
60022
|
+
);
|
|
60023
|
+
}
|
|
60024
|
+
if (!opts.json) {
|
|
60025
|
+
out(` ${dim(n.ok ? `Payer ${short} holds ${formatNativeHeld(n)}; checked against the exact amount once the order is priced.` : `Payer ${short}: ${opts.source.tokenSymbol} balance not checked (${n.reason}).`)}`);
|
|
60026
|
+
}
|
|
60027
|
+
payer = { address: opts.payer, family };
|
|
60028
|
+
} else {
|
|
60029
|
+
const result = await fetchWalletOptions({ address: opts.payer, usdRequired: invoiceUsd });
|
|
60030
|
+
if (isProvablyShort(opts.source, result)) {
|
|
60031
|
+
throw new SkillErrorLike(
|
|
60032
|
+
"INSUFFICIENT_BALANCE",
|
|
60033
|
+
`${opts.payer.slice(0, 6)}\u2026${opts.payer.slice(-4)} does not appear to hold enough ${opts.source.tokenSymbol} for a $${invoiceUsd} invoice. Choose another coin, or omit --payer to proceed anyway from a different wallet.`
|
|
60034
|
+
);
|
|
60035
|
+
}
|
|
60036
|
+
if (!result.ok && !opts.json) {
|
|
60037
|
+
out(` ${yellow(`Could not check balances (${result.reason}). Continuing.`)}`);
|
|
60038
|
+
} else if (result.ok && !opts.json) {
|
|
60039
|
+
const hit = (result.options ?? []).find(
|
|
60040
|
+
(o) => o.chainId === String(opts.source.chainId) && o.tokenSymbol === String(opts.source.tokenSymbol).toUpperCase()
|
|
60041
|
+
);
|
|
60042
|
+
const short = `${opts.payer.slice(0, 6)}\u2026${opts.payer.slice(-4)}`;
|
|
60043
|
+
if (hit?.balanceUsd != null) {
|
|
60044
|
+
out(` ${dim(`Payer ${short} holds about $${hit.balanceUsd} of ${opts.source.tokenSymbol} \u2014 enough for this invoice.`)}`);
|
|
60045
|
+
} else {
|
|
60046
|
+
out(` ${dim(`Payer ${short}: balance not reported for this coin, so it was not verified.`)}`);
|
|
60047
|
+
}
|
|
59357
60048
|
}
|
|
60049
|
+
payer = { address: opts.payer, family };
|
|
59358
60050
|
}
|
|
59359
|
-
payer = { address: opts.payer, family };
|
|
59360
60051
|
}
|
|
59361
60052
|
const { chainId, tokenSymbol } = opts.source;
|
|
59362
60053
|
const createFlow = opts.bitrefill ? run3 : run2;
|
|
@@ -59420,8 +60111,14 @@ async function cmdPay(opts) {
|
|
|
59420
60111
|
out(` Memo ${p.display.receiverMemoMasked} ${dim(`(${p.display.memoType})`)}`);
|
|
59421
60112
|
}
|
|
59422
60113
|
const deadline = formatDeadline(p.expiry?.effectiveDeadlineIso);
|
|
59423
|
-
|
|
59424
|
-
|
|
60114
|
+
if (p.display?.native) {
|
|
60115
|
+
out(` Price ${bold(`locked ${deadline ?? `for ${p.expiry?.expiresIn ?? "?"}`}`)}`);
|
|
60116
|
+
out(` ${dim("Send exactly this amount before then. After that, do not send it: start a new order.")}`);
|
|
60117
|
+
out(` ${dim("The coin amount includes an FX spread on top of the service fee.")}`);
|
|
60118
|
+
} else {
|
|
60119
|
+
out(` Expires ${bold(deadline ?? `in ${p.expiry?.expiresIn ?? "?"}`)}`);
|
|
60120
|
+
out(` ${dim("After that this order cannot be used and a new one must be created.")}`);
|
|
60121
|
+
}
|
|
59425
60122
|
out(
|
|
59426
60123
|
p.reused ? ` ${dim(`Reusing existing unpaid order ${p.rozoPaymentId} \u2014 nothing new was created.`)}` : ` ${dim(`Order created: ${p.rozoPaymentId}`)}`
|
|
59427
60124
|
);
|
|
@@ -59438,6 +60135,39 @@ async function cmdPay(opts) {
|
|
|
59438
60135
|
for (const w of p.confirmation?.warnings ?? []) out(dim(` \xB7 ${w}`));
|
|
59439
60136
|
out();
|
|
59440
60137
|
}
|
|
60138
|
+
if (payer && p.display?.native && p.display?.coinAmount) {
|
|
60139
|
+
const n = await fetchNativeBalance({ chainId, address: payer.address });
|
|
60140
|
+
if (n.ok) {
|
|
60141
|
+
let amountAtomic = null;
|
|
60142
|
+
try {
|
|
60143
|
+
amountAtomic = toAtomic(p.display.coinAmount, decimalsFor(chainId, tokenSymbol));
|
|
60144
|
+
} catch {
|
|
60145
|
+
amountAtomic = null;
|
|
60146
|
+
}
|
|
60147
|
+
if (amountAtomic !== null) {
|
|
60148
|
+
const verdict = assessNative({ balanceAtomic: n.balanceAtomic, headroomAtomic: n.headroomAtomic, amountAtomic });
|
|
60149
|
+
const short = `${payer.address.slice(0, 6)}\u2026${payer.address.slice(-4)}`;
|
|
60150
|
+
const need = `${p.display.coinAmount} ${tokenSymbol} plus about ${formatAtomic(n.headroomAtomic, n.decimals)} ${tokenSymbol} for gas`;
|
|
60151
|
+
if (verdict.mark === "insufficient" && opts.payer && !chosenPreset) {
|
|
60152
|
+
const payload = formatFailure({
|
|
60153
|
+
code: "INSUFFICIENT_BALANCE",
|
|
60154
|
+
message: `${short} holds ${formatNativeHeld(n)}; this order needs ${need}. Nothing was sent. The unfunded order simply expires. Choose another coin, or omit --payer to pay from a different wallet.`
|
|
60155
|
+
});
|
|
60156
|
+
if (opts.json) printJson(payload);
|
|
60157
|
+
else printError(payload);
|
|
60158
|
+
return EXIT_ERROR;
|
|
60159
|
+
}
|
|
60160
|
+
if (!opts.json) {
|
|
60161
|
+
if (verdict.mark === "affordable") {
|
|
60162
|
+
out(` ${dim(`Payer ${short} holds ${formatNativeHeld(n)}: enough for ${need}.`)}`);
|
|
60163
|
+
} else {
|
|
60164
|
+
out(` ${yellow(`Payer ${short} holds ${formatNativeHeld(n)}, but this order needs ${need}.`)}`);
|
|
60165
|
+
}
|
|
60166
|
+
out();
|
|
60167
|
+
}
|
|
60168
|
+
}
|
|
60169
|
+
}
|
|
60170
|
+
}
|
|
59441
60171
|
if (!opts.yes) {
|
|
59442
60172
|
if (!process.stdin.isTTY) {
|
|
59443
60173
|
const payload = formatFailure({
|
|
@@ -59578,7 +60308,13 @@ function printDeposit(deposit, opts) {
|
|
|
59578
60308
|
` Memo ${bold(deposit.receiverMemo)} ${red(`(required, ${deposit.receiverMemoType})`)}`
|
|
59579
60309
|
);
|
|
59580
60310
|
}
|
|
59581
|
-
if (deposit.
|
|
60311
|
+
if (deposit.native) {
|
|
60312
|
+
if (deposit.expiresIn) out(` Price locked for ${bold(deposit.expiresIn)} more`);
|
|
60313
|
+
const lock = formatDeadline(deposit.quoteExpiresAt);
|
|
60314
|
+
if (lock) out(` ${dim(`(${lock})`)}`);
|
|
60315
|
+
} else if (deposit.expiresIn) {
|
|
60316
|
+
out(` Expires in ${bold(deposit.expiresIn)}`);
|
|
60317
|
+
}
|
|
59582
60318
|
}
|
|
59583
60319
|
out();
|
|
59584
60320
|
const unit = isSatsUnit(deposit.amountUnit) ? "sats" : deposit.tokenSymbol;
|
|
@@ -59586,6 +60322,11 @@ function printDeposit(deposit, opts) {
|
|
|
59586
60322
|
out(
|
|
59587
60323
|
` Make sure the wallet you pay from holds at least ${bold(`${deposit.amount} ${unit}`)} ${where}.`
|
|
59588
60324
|
);
|
|
60325
|
+
if (deposit.native) {
|
|
60326
|
+
out(dim(` Plus a little ${deposit.tokenSymbol} for the network fee. The amount that arrives must be`));
|
|
60327
|
+
out(dim(" exactly the amount above: from an exchange, check its withdrawal fee is not taken from it."));
|
|
60328
|
+
out(dim(" After the price lock ends, do not send: start a new order."));
|
|
60329
|
+
}
|
|
59589
60330
|
out(dim(" Copy the address from this block; do not retype it."));
|
|
59590
60331
|
out(dim(" Send it exactly once."));
|
|
59591
60332
|
out();
|