From 0289c23fc22cc90c05aff8de9249cab4dd160598 Mon Sep 17 00:00:00 2001 From: Nicolas Brugneaux Date: Tue, 27 Aug 2024 17:11:40 +0200 Subject: [PATCH 1/9] wip: use data/value for feecurrency --- .env.example | 2 + src/cip64.ts | 40 +++++++-- src/index.ts | 202 ++++++++++++++++++++++++++++++++++++++---- src/tests/e2e.test.ts | 101 +++++++++++++++++++++ typedoc.json | 19 ---- 5 files changed, 321 insertions(+), 43 deletions(-) create mode 100644 .env.example create mode 100644 src/tests/e2e.test.ts delete mode 100644 typedoc.json diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..9d8289d --- /dev/null +++ b/.env.example @@ -0,0 +1,2 @@ +TEST_ACCOUNT_1="0x0000000000000000000000000000000000000000000000000000000000000000" +TEST_ACCOUNT_2="0x0000000000000000000000000000000000000000000000000000000000000000" \ No newline at end of file diff --git a/src/cip64.ts b/src/cip64.ts index 12a3f76..2b640cb 100644 --- a/src/cip64.ts +++ b/src/cip64.ts @@ -162,12 +162,39 @@ export class CIP64Transaction extends BaseTransaction { ); } public constructor(txData: CIP64Data, opts: TxOptions = {}) { + const { + chainId, + accessList, + maxFeePerGas, + maxPriorityFeePerGas, + data, + value, + feeCurrency: _feeCurrency, + } = txData; + + let feeCurrency: Address; + + // NOTE: hack, we're storing the feeCurrency in value + // for contract calls + if (typeof value === "string" && value.match(/^0x[0-9a-f]{40}$/i)) { + feeCurrency = value as string; + txData.value = 0; + } else if (typeof data === "string") { + // NOTE: hack, we're storing the feeCurrency in data + // 42 = 0x + 40 (feeCurrency address) + feeCurrency = (data as string)?.slice(0, 42); + txData.data = `0x${(data as string).slice(42)}`; + } else { + // NOTE: We arrive here when called by `fromTxData` directly, all is good + feeCurrency = _feeCurrency; + } + super({ ...txData, type: TxTypeToPrefix.cip64 }, opts); - const { chainId, accessList, maxFeePerGas, maxPriorityFeePerGas } = txData; this.common = this._getCommon(opts.common, chainId); this.chainId = this.common.chainId(); - this.feeCurrency = txData.feeCurrency; + + this.feeCurrency = feeCurrency; // Populate the access list fields const accessListData = getAccessListData(accessList ?? []); @@ -176,9 +203,6 @@ export class CIP64Transaction extends BaseTransaction { // Verify the access list format. verifyAccessList(this.accessList); - // TODO: whitelist - // verifyFeeCurrency(this.feeCurrency); - this.maxFeePerGas = uint8ArrayToBigInt( toUint8Array(maxFeePerGas === "" ? "0x" : maxFeePerGas) ); @@ -217,7 +241,6 @@ export class CIP64Transaction extends BaseTransaction { } public getDataFee(): bigint { - // TODO adjust for feeCurrency if ( this.cache.dataFee && this.cache.dataFee.hardfork === this.common.hardfork() @@ -239,7 +262,6 @@ export class CIP64Transaction extends BaseTransaction { } public getUpfrontCost(baseFee = BigInt(0)): bigint { - // TODO adjust for feeCurrency const prio = this.maxPriorityFeePerGas; const maxBase = this.maxFeePerGas - baseFee; const inclusionFeePerGas = prio < maxBase ? prio : maxBase; @@ -256,9 +278,9 @@ export class CIP64Transaction extends BaseTransaction { bigIntToUnpaddedUint8Array(this.gasLimit), this.to !== undefined ? this.to.buf : Uint8Array.from([]), bigIntToUnpaddedUint8Array(this.value), - this.data, + bytesToHex(this.feeCurrency), this.accessList, - unpadUint8Array(hexToBytes(this.feeCurrency)), + hexToBytes(this.feeCurrency), this.v !== undefined ? bigIntToUnpaddedUint8Array(this.v) : Uint8Array.from([]), diff --git a/src/index.ts b/src/index.ts index f261a1f..4b36384 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,5 +1,12 @@ // create new TransactionType class which extends BaseTransaction class -import { Address, Web3Context, Web3PluginBase } from "web3"; +import { + Address, + Contract, + ContractAbi, + HexString, + Web3Context, + Web3PluginBase, +} from "web3"; import { TransactionFactory } from "web3-eth-accounts"; import { CIP64Transaction } from "./cip64"; import { @@ -12,24 +19,20 @@ import { type TransactionMiddlewareData, type TransactionMiddleware, } from "web3/src/eth.exports"; - -// create new plugin and add `SomeNewTxTypeTransaction` to the library +import { type TransactionBuilder } from "web3-core"; +import { transactionBuilder } from "web3-eth"; +import { bytesToHex, hexToBytes, uint8ArrayConcat } from "web3-utils"; export class CeloTransactionTypesPlugin extends Web3PluginBase { + public static TX_TYPE = BigInt(parseInt(TxTypeToPrefix.cip64)); public pluginNamespace = "celo" as const; public constructor() { super(); TransactionFactory.registerTransactionType( - TxTypeToPrefix.cip64, + CeloTransactionTypesPlugin.TX_TYPE, CIP64Transaction ); - this.defaultTransactionType = TxTypeToPrefix.cip64; - - // TransactionFactory.registerTransactionType( - // TxTypeToPrefix.cip66, - // CIP66Transaction - // ); } public async isValidFeeCurrency(feeCurrency: Address) { @@ -46,19 +49,185 @@ export class CeloTransactionTypesPlugin extends Web3PluginBase { public link(parentContext: Web3Context): void { (parentContext as any).Web3Eth.setTransactionMiddleware( - new CeloTxMiddleware() + new CeloTxMiddleware(parentContext) ); super.link(parentContext); } } -export class CeloTxMiddleware implements TransactionMiddleware { +export class CeloContract extends Contract { + constructor(...args: ConstructorParameters) { + let [ + jsonInterface, + addressOrOptionsOrContext, + optionsOrContextOrReturnFormat, + contextOrReturnFormat, + returnFormat, + ] = args; + + super( + // @ts-expect-error + jsonInterface, + addressOrOptionsOrContext, + optionsOrContextOrReturnFormat, + contextOrReturnFormat, + returnFormat + ); + + let contractContext; + if ((addressOrOptionsOrContext as unknown) instanceof Web3Context) { + contractContext = addressOrOptionsOrContext; + } else if (optionsOrContextOrReturnFormat instanceof Web3Context) { + contractContext = optionsOrContextOrReturnFormat; + } else { + contractContext = contextOrReturnFormat; + } + + if (contractContext instanceof Web3Context) { + this.setTransactionMiddleware(new CeloTxMiddleware(contractContext)); + } + } +} + +class CeloTxMiddleware implements TransactionMiddleware { + constructor(private ctx: Web3Context) { + const celoTransactionBuilder = (async (options) => { + const { + transaction: { value, type, data, ...transaction }, + } = options; + + // NOTE: hack, we're storing the feeCurrency in value + // for contract calls + const valueAsFeeCurrencyForContractCalls = + typeof value === "string" && value.match(/^0x[0-9a-f]{40}$/i); + const isCip64 = + valueAsFeeCurrencyForContractCalls || + (type && BigInt(type as string) === CeloTransactionTypesPlugin.TX_TYPE); + + // NOTE: hack, we're storing the feeCurrency in data + // 42 = 0x + 40 (feeCurrency address) + const feeCurrency = isCip64 + ? valueAsFeeCurrencyForContractCalls + ? (value as string) + : (data as string).slice(0, 42) + : undefined; + const _data = + isCip64 && !valueAsFeeCurrencyForContractCalls + ? (data as string).slice(42) + : data; + + console.log("here!", { + value, + data, + valueAsFeeCurrencyForContractCalls, + isCip64, + feeCurrency, + _data, + }); + // NOTE: small hack + this.ctx.transactionBuilder = undefined; + + const tx = await transactionBuilder({ + ...options, + transaction: { + ...transaction, + value: valueAsFeeCurrencyForContractCalls ? undefined : value, + type, + data: _data, + }, + }); + this.ctx.transactionBuilder = celoTransactionBuilder; + // NOTE: end hack + + if (!isCip64) { + return tx; + } + + if (!(await this.ctx.celo.isValidFeeCurrency(feeCurrency!))) { + throw new Error(`${feeCurrency} is not a whitelisted feeCurrency`); + } + tx.type = CeloTransactionTypesPlugin.TX_TYPE; + tx.feeCurrency = feeCurrency; + + if (!tx.maxPriorityFeePerGas) { + const rpcResult = (await options.web3Context.requestManager.send({ + method: "eth_maxPriorityFeePerGas", + params: [feeCurrency], + })) as HexString; + tx.maxPriorityFeePerGas = rpcResult; + } + if (!tx.maxFeePerGas) { + const rpcResult = (await options.web3Context.requestManager.send({ + method: "eth_gasPrice", + params: [feeCurrency], + })) as HexString; + tx.maxFeePerGas = rpcResult; + } + tx.data = data; + + const gas = await options.web3Context.requestManager.send({ + method: "eth_estimateGas", + params: [ + { + ...transaction, + value: valueAsFeeCurrencyForContractCalls ? undefined : value, + type, + data: _data, + nonce: tx.nonce, + chainId: tx.chainId, + networkId: tx.networkId, + feeCurrency, + maxPriorityFeePerGas: tx.maxPriorityFeePerGas, + maxFeePerGas: tx.maxFeePerGas, + }, + "latest", + ], + }); + tx.gas = (BigInt(gas) * BigInt(130)) / BigInt(100); + + if (valueAsFeeCurrencyForContractCalls) { + tx.value = feeCurrency; + } + + return tx; + }) as TransactionBuilder; + + this.ctx.transactionBuilder = celoTransactionBuilder; + } public async processTransaction( transaction: TransactionMiddlewareData ): Promise { - const txObj = { ...transaction }; - console.log("Transaction data:", txObj); - return Promise.resolve(txObj); + console.log("HELLO!", transaction); + const { feeCurrency, gasPrice } = transaction; + // Not CELO specific + if (!feeCurrency) { + return transaction; + } + if (gasPrice) { + throw new Error(`gasPrice shouldn't be used with feeCurrency`); + } + + const tx = { ...transaction }; + tx.type = CeloTransactionTypesPlugin.TX_TYPE; + + if (tx.data) { + // NOTE: hack, we're storing the feeCurrency in value + // for contract calls + if (!tx.value) { + tx.value = feeCurrency; + } else { + // NOTE: hack, we're storing the feeCurrency in data + tx.data = uint8ArrayConcat( + hexToBytes(feeCurrency), + typeof tx.data === "string" ? hexToBytes(tx.data) : tx.data + ); + } + } else { + // NOTE: hack, we're storing the feeCurrency in data + tx.data = hexToBytes(feeCurrency); + } + + return tx; } } @@ -69,4 +238,7 @@ declare module "web3" { interface NonPayableCallOptions { feeCurrency?: Address; } + interface Transaction { + feeCurrency?: Address; + } } diff --git a/src/tests/e2e.test.ts b/src/tests/e2e.test.ts new file mode 100644 index 0000000..b6c0fc1 --- /dev/null +++ b/src/tests/e2e.test.ts @@ -0,0 +1,101 @@ +import { testWithAnvilL1 } from "@celo/dev-utils/lib/anvil-test"; +import { beforeAll, expect, test } from "bun:test"; +import { CeloContract, CeloTransactionTypesPlugin } from ".."; +import Web3, { + Address, + Contract, + DataFormat, + FMT_BYTES, + FMT_NUMBER, +} from "web3"; +import { stableTokenEurABI } from "@celo/abis"; +import { hexToBytes, toWei } from "web3-utils"; +import { CeloChains, TxTypeToPrefix } from "../utils"; +import { waitForTransactionReceipt } from "web3-eth"; +import { CIP64Transaction } from "../cip64"; + +let stable: CeloContract; +let stableAddress: Address; + +const web3 = new Web3(CeloChains.alfajores.rpcUrl); +const account = web3.eth.accounts.privateKeyToAccount( + process.env.TEST_ACCOUNT_1 as string +); +const account2 = web3.eth.accounts.privateKeyToAccount( + process.env.TEST_ACCOUNT_2 as string +); +web3.eth.accounts.wallet?.add(account); + +beforeAll(async () => { + web3.registerPlugin(new CeloTransactionTypesPlugin()); + web3.celo.link(web3); + stableAddress = await web3.celo.getCoreContractAddress("StableTokenEUR"); + stable = new CeloContract(stableTokenEurABI, stableAddress, web3); + + web3.eth.defaultAccount = account.address; +}); + +test.only( + "can do a transaction", + async () => { + const amount = BigInt(10); + const balanceSenderBefore = BigInt( + await stable.methods.balanceOf(account.address).call() + ); + const balanceReceiverBefore = BigInt( + await stable.methods.balanceOf(account2.address).call() + ); + + const tx = await stable.methods.transfer(account2.address, amount).send({ + from: web3.eth.defaultAccount, + feeCurrency: stableAddress, + }); + + const balanceSenderAfter = BigInt( + await stable.methods.balanceOf(account.address).call() + ); + const balanceReceiverAfter = BigInt( + await stable.methods.balanceOf(account2.address).call() + ); + + expect(tx.transactionHash).toMatch(/^0x[0-9a-f]{64}$/i); + expect(balanceSenderAfter).toBeLessThanOrEqual( + balanceSenderBefore - amount + ); + expect(balanceReceiverAfter).toEqual(balanceReceiverBefore + amount); + }, + { timeout: 10_000 } +); + +test( + "can do a transaction with feeCurrency", + async () => { + const amount = BigInt(10); + const stableBalanceSenderBefore = BigInt( + await stable.methods.balanceOf(account.address).call() + ); + const nativeBalanceBefore = BigInt( + await web3.eth.getBalance(account.address) + ); + + const txData = { + from: web3.eth.defaultAccount, + to: account2.address, + value: amount, + feeCurrency: stableAddress, + }; + const tx = await web3.eth.sendTransaction(txData); + const stableBalanceSenderAfter = BigInt( + await stable.methods.balanceOf(account.address).call() + ); + const nativeBalanceAfter = BigInt( + await web3.eth.getBalance(account.address) + ); + + expect(tx.transactionHash).toMatch(/^0x[0-9a-f]{64}$/i); + console.log({ tx }); + expect(stableBalanceSenderAfter).toBeLessThan(stableBalanceSenderBefore); + expect(nativeBalanceBefore).toEqual(nativeBalanceAfter + amount); + }, + { timeout: 10_000 } +); diff --git a/typedoc.json b/typedoc.json deleted file mode 100644 index 5c96e64..0000000 --- a/typedoc.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "exclude": [ - "**/*+(index|.test).ts" - ], - "excludePrivate": true, - "excludeProtected": true, - "hideGenerator": true, - "out": "../../../docs/sdk/base", - "gitRevision": "master", - "readme": "none", - "entryPoints": [ - "./src" - ], - "githubPages": false, - "plugin": [ - "typedoc-plugin-markdown" - ], - "entryPointStrategy": "expand" -} \ No newline at end of file From 96c862e800832f6c4c0b4f0249e366817d7e9687 Mon Sep 17 00:00:00 2001 From: Nicolas Brugneaux Date: Fri, 20 Sep 2024 09:54:23 +0200 Subject: [PATCH 2/9] refactor: use web3 4.13.0 --- bun.lockb | Bin 240232 -> 273192 bytes package.json | 6 +- src/cip64.ts | 21 +--- src/index.ts | 235 ++++++++++++++++++++---------------------- src/tests/e2e.test.ts | 11 +- src/utils.ts | 14 ++- 6 files changed, 138 insertions(+), 149 deletions(-) diff --git a/bun.lockb b/bun.lockb index 3e1afa08b0301e912e31e4d4519364ad958d6a2d..98fc081066b8e1d29afbef589981ba73c9d21eb5 100755 GIT binary patch delta 68075 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 KH~)6`r2hvd|Gahp delta 48551 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�nfGa&DkusN{Q2e{e2aIT%4<&Ebatu`(f`(m zktb7AZ{g(}ypD4CRUUwP>ce*l%WwRK)iqdp@q|uZ!o=>PVMg2mwGYw0D8!2+@Af6J zp;B;bNW+NexbFiiIJc10gIl#!V?^b)tsQ&vQx<2<>{>%0!3Q@eQ}o#uVA5FU?#XKQ>U`(qy9( zlilZ=@SuF(mkqA<+RbNS(!BuxR{cSTedqPdv%WzGSKAE@hqvg9U+r-lZ9d`6T^+hD zeEHuGZKnw>`DW6olk*!oE`A4zH78(oR^+JH29%~AMw_eXuf?a`e_Zc$>!ch%7Pq(G z6E**8`dp4*ziM22*gt;XKhfri>h=05N5kW1uSxm=9S-Oy?Yr4FcTn)+1Y@!>W?r18 zZ0E9ZzxM4El#h_Z$Ma7==zFA8+r0p7PH+e3Pj)>uI^@-sILj%9i7o zS)VbnByve-Pg;vi>>d2H^JO;Bx?mAIqty;8*vI-&)MB=S66^6ka(+6B7`s2kZQb2H{N_IqR^{Hk@ZS0kNz%2%hNzI^sXIOuVN@cdzr$1)P>}j2ub*J~=VNX*) zJhP=YYcSpJ&)MEVb_uD*n7H^wNpA5bTK6`4gQ%R1vZg;|**5kjV|-kyTlAuMe9^sM z*>wuu#R3jC*d%wR=@o1sHB~To>YB`)t+8EfPIRS!hpY$PeFwWA= 4.0.2 < 5" + "web3": ">= 4.13.0 < 5" }, "devDependencies": { "@celo/dev-utils": "^0.0.5", @@ -37,12 +37,12 @@ "eslint-plugin-jest": "^28.6.0", "typescript": "^5.5.4", "typescript-eslint": "^7.17.0", - "web3": "^4.11.1" + "web3": "^4.13.0" }, "dependencies": { "@celo/abis": "^11.0.0", "@celo/abis-l2": "npm:@celo/abis@12.0.0-canary.23", - "web3-eth-accounts": "^4.1.3", + "web3-eth-accounts": "^4.2.1", "web3-utils": "^4.3.1" }, "patchedDependencies": { diff --git a/src/cip64.ts b/src/cip64.ts index 2b640cb..0d969e6 100644 --- a/src/cip64.ts +++ b/src/cip64.ts @@ -167,28 +167,9 @@ export class CIP64Transaction extends BaseTransaction { accessList, maxFeePerGas, maxPriorityFeePerGas, - data, - value, - feeCurrency: _feeCurrency, + feeCurrency, } = txData; - let feeCurrency: Address; - - // NOTE: hack, we're storing the feeCurrency in value - // for contract calls - if (typeof value === "string" && value.match(/^0x[0-9a-f]{40}$/i)) { - feeCurrency = value as string; - txData.value = 0; - } else if (typeof data === "string") { - // NOTE: hack, we're storing the feeCurrency in data - // 42 = 0x + 40 (feeCurrency address) - feeCurrency = (data as string)?.slice(0, 42); - txData.data = `0x${(data as string).slice(42)}`; - } else { - // NOTE: We arrive here when called by `fromTxData` directly, all is good - feeCurrency = _feeCurrency; - } - super({ ...txData, type: TxTypeToPrefix.cip64 }, opts); this.common = this._getCommon(opts.common, chainId); diff --git a/src/index.ts b/src/index.ts index 4b36384..de10c52 100644 --- a/src/index.ts +++ b/src/index.ts @@ -4,6 +4,8 @@ import { Contract, ContractAbi, HexString, + Numbers, + Transaction, Web3Context, Web3PluginBase, } from "web3"; @@ -13,6 +15,7 @@ import { getContractAddressFromRegistry, isCel2, isWhitelisted, + safeTxForRpc, TxTypeToPrefix, } from "./utils"; import { @@ -20,8 +23,7 @@ import { type TransactionMiddleware, } from "web3/src/eth.exports"; import { type TransactionBuilder } from "web3-core"; -import { transactionBuilder } from "web3-eth"; -import { bytesToHex, hexToBytes, uint8ArrayConcat } from "web3-utils"; +import { transactionBuilder, transactionSchema } from "web3-eth"; export class CeloTransactionTypesPlugin extends Web3PluginBase { public static TX_TYPE = BigInt(parseInt(TxTypeToPrefix.cip64)); @@ -47,6 +49,72 @@ export class CeloTransactionTypesPlugin extends Web3PluginBase { return getContractAddressFromRegistry(this, contractName); } + public async populateTransaction(tx: Transaction) { + const { feeCurrency } = tx; + + const promises: Promise<[string, Numbers]>[] = []; + if (!tx.nonce) { + promises.push( + this.requestManager + .send({ + method: "eth_getTransactionCount", + params: [tx.from, "latest"], + }) + .then((x) => ["nonce", x]) + ); + } + if (!tx.chainId) { + promises.push( + this.requestManager + .send({ + method: "eth_chainId", + params: [], + }) + .then((x) => ["chainId", x]) + ); + } + if (!tx.maxPriorityFeePerGas) { + promises.push( + this.requestManager + .send({ + method: "eth_maxPriorityFeePerGas", + params: feeCurrency ? [feeCurrency] : [], + }) + .then((x: HexString) => ["maxPriorityFeePerGas", BigInt(x)]) + ); + } + if (!tx.maxFeePerGas) { + promises.push( + this.requestManager + .send({ + method: "eth_gasPrice", + params: feeCurrency ? [feeCurrency] : [], + }) + .then((x: HexString) => ["maxFeePerGas", BigInt(x)]) + ); + } + + (await Promise.all(promises)).forEach(([key, value]) => { + // @ts-expect-error + tx[key] = value; + }); + + const gas = await this.requestManager.send({ + method: "eth_estimateGas", + params: [ + { + ...safeTxForRpc(tx), + gas: undefined, + }, + "latest", + ], + }); + // TODO: add note for inflation factor + tx.gas = (BigInt(gas) * BigInt(130)) / BigInt(100); + + return safeTxForRpc(tx); + } + public link(parentContext: Web3Context): void { (parentContext as any).Web3Eth.setTransactionMiddleware( new CeloTxMiddleware(parentContext) @@ -89,117 +157,26 @@ export class CeloContract extends Contract { } } +type CeloTransaction = Transaction & { + feeCurrency?: HexString; +}; + class CeloTxMiddleware implements TransactionMiddleware { constructor(private ctx: Web3Context) { - const celoTransactionBuilder = (async (options) => { - const { - transaction: { value, type, data, ...transaction }, - } = options; - - // NOTE: hack, we're storing the feeCurrency in value - // for contract calls - const valueAsFeeCurrencyForContractCalls = - typeof value === "string" && value.match(/^0x[0-9a-f]{40}$/i); - const isCip64 = - valueAsFeeCurrencyForContractCalls || - (type && BigInt(type as string) === CeloTransactionTypesPlugin.TX_TYPE); - - // NOTE: hack, we're storing the feeCurrency in data - // 42 = 0x + 40 (feeCurrency address) - const feeCurrency = isCip64 - ? valueAsFeeCurrencyForContractCalls - ? (value as string) - : (data as string).slice(0, 42) - : undefined; - const _data = - isCip64 && !valueAsFeeCurrencyForContractCalls - ? (data as string).slice(42) - : data; - - console.log("here!", { - value, - data, - valueAsFeeCurrencyForContractCalls, - isCip64, - feeCurrency, - _data, - }); - // NOTE: small hack - this.ctx.transactionBuilder = undefined; - - const tx = await transactionBuilder({ - ...options, - transaction: { - ...transaction, - value: valueAsFeeCurrencyForContractCalls ? undefined : value, - type, - data: _data, - }, - }); - this.ctx.transactionBuilder = celoTransactionBuilder; - // NOTE: end hack - - if (!isCip64) { - return tx; - } - - if (!(await this.ctx.celo.isValidFeeCurrency(feeCurrency!))) { - throw new Error(`${feeCurrency} is not a whitelisted feeCurrency`); - } - tx.type = CeloTransactionTypesPlugin.TX_TYPE; - tx.feeCurrency = feeCurrency; - - if (!tx.maxPriorityFeePerGas) { - const rpcResult = (await options.web3Context.requestManager.send({ - method: "eth_maxPriorityFeePerGas", - params: [feeCurrency], - })) as HexString; - tx.maxPriorityFeePerGas = rpcResult; - } - if (!tx.maxFeePerGas) { - const rpcResult = (await options.web3Context.requestManager.send({ - method: "eth_gasPrice", - params: [feeCurrency], - })) as HexString; - tx.maxFeePerGas = rpcResult; - } - tx.data = data; - - const gas = await options.web3Context.requestManager.send({ - method: "eth_estimateGas", - params: [ - { - ...transaction, - value: valueAsFeeCurrencyForContractCalls ? undefined : value, - type, - data: _data, - nonce: tx.nonce, - chainId: tx.chainId, - networkId: tx.networkId, - feeCurrency, - maxPriorityFeePerGas: tx.maxPriorityFeePerGas, - maxFeePerGas: tx.maxFeePerGas, - }, - "latest", - ], - }); - tx.gas = (BigInt(gas) * BigInt(130)) / BigInt(100); - - if (valueAsFeeCurrencyForContractCalls) { - tx.value = feeCurrency; - } - - return tx; - }) as TransactionBuilder; - - this.ctx.transactionBuilder = celoTransactionBuilder; + this.ctx.config.customTransactionSchema = { + ...transactionSchema, + properties: { + ...transactionSchema.properties, + feeCurrency: { format: "address" }, + }, + }; + this.ctx.transactionBuilder = this.transactionBuilder as TransactionBuilder; } + public async processTransaction( transaction: TransactionMiddlewareData ): Promise { - console.log("HELLO!", transaction); const { feeCurrency, gasPrice } = transaction; - // Not CELO specific if (!feeCurrency) { return transaction; } @@ -210,25 +187,39 @@ class CeloTxMiddleware implements TransactionMiddleware { const tx = { ...transaction }; tx.type = CeloTransactionTypesPlugin.TX_TYPE; - if (tx.data) { - // NOTE: hack, we're storing the feeCurrency in value - // for contract calls - if (!tx.value) { - tx.value = feeCurrency; - } else { - // NOTE: hack, we're storing the feeCurrency in data - tx.data = uint8ArrayConcat( - hexToBytes(feeCurrency), - typeof tx.data === "string" ? hexToBytes(tx.data) : tx.data - ); - } - } else { - // NOTE: hack, we're storing the feeCurrency in data - tx.data = hexToBytes(feeCurrency); + return tx; + } + + private transactionBuilder = async ( + options: Parameters[0] + ) => { + const { transaction } = options; + + // NOTE: small hack: + // `transactionBuilder` calls this.ctx.transactionBuilder if defined + this.ctx.transactionBuilder = undefined; + const tx: CeloTransaction = await transactionBuilder({ + ...options, + transaction: transaction, + }); + tx.feeCurrency = transaction.feeCurrency; + + this.ctx.transactionBuilder = this.transactionBuilder as TransactionBuilder; + // NOTE: end hack + + const { feeCurrency } = tx; + if (!feeCurrency || feeCurrency === "0x") { + return transaction; + } + + if (!(await this.ctx.celo.isValidFeeCurrency(feeCurrency!))) { + throw new Error(`${feeCurrency} is not a whitelisted feeCurrency`); } + await this.ctx.celo.populateTransaction(tx); + return tx; - } + }; } declare module "web3" { diff --git a/src/tests/e2e.test.ts b/src/tests/e2e.test.ts index b6c0fc1..5b8978a 100644 --- a/src/tests/e2e.test.ts +++ b/src/tests/e2e.test.ts @@ -29,13 +29,19 @@ web3.eth.accounts.wallet?.add(account); beforeAll(async () => { web3.registerPlugin(new CeloTransactionTypesPlugin()); web3.celo.link(web3); + + // NOTE: This is a hack I think, whenever we use web3.eth.sendTransaction + // it looses the celo context and can't serialize cip64 txs + web3.eth.config.customTransactionSchema = + web3.celo.config.customTransactionSchema; + stableAddress = await web3.celo.getCoreContractAddress("StableTokenEUR"); stable = new CeloContract(stableTokenEurABI, stableAddress, web3); web3.eth.defaultAccount = account.address; }); -test.only( +test( "can do a transaction", async () => { const amount = BigInt(10); @@ -77,13 +83,13 @@ test( const nativeBalanceBefore = BigInt( await web3.eth.getBalance(account.address) ); - const txData = { from: web3.eth.defaultAccount, to: account2.address, value: amount, feeCurrency: stableAddress, }; + await web3.celo.populateTransaction(txData); const tx = await web3.eth.sendTransaction(txData); const stableBalanceSenderAfter = BigInt( await stable.methods.balanceOf(account.address).call() @@ -93,7 +99,6 @@ test( ); expect(tx.transactionHash).toMatch(/^0x[0-9a-f]{64}$/i); - console.log({ tx }); expect(stableBalanceSenderAfter).toBeLessThan(stableBalanceSenderBefore); expect(nativeBalanceBefore).toEqual(nativeBalanceAfter + amount); }, diff --git a/src/utils.ts b/src/utils.ts index d4e1f01..0fe2492 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,6 +1,6 @@ import { registryABI, feeCurrencyWhitelistABI } from "@celo/abis"; import { feeCurrencyDirectoryABI } from "@celo/abis-l2"; -import Web3, { Address, Contract } from "web3"; +import Web3, { Address, Contract, Transaction } from "web3"; import { CeloTransactionTypesPlugin } from "."; export enum TxTypeToPrefix { @@ -92,3 +92,15 @@ export async function isWhitelisted( .map((x) => x.toLowerCase()) .includes(feeCurrency.toLowerCase()); } + +export function safeTxForRpc(transaction: T): T { + const tx = { ...transaction }; + const entries = Object.entries(transaction) as [keyof T, any][]; + for (const [key, value] of entries) { + if (typeof value === "bigint" || typeof value === "number") { + // @ts-expect-error + tx[key] = `0x${value.toString(16)}`; + } + } + return tx; +} From 944a212e3aaab827b67cea023dc6647c4a69dc44 Mon Sep 17 00:00:00 2001 From: Nicolas Brugneaux Date: Tue, 24 Sep 2024 09:22:27 +0200 Subject: [PATCH 3/9] fix: serializing --- src/cip64.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cip64.ts b/src/cip64.ts index 0d969e6..1de8929 100644 --- a/src/cip64.ts +++ b/src/cip64.ts @@ -259,7 +259,7 @@ export class CIP64Transaction extends BaseTransaction { bigIntToUnpaddedUint8Array(this.gasLimit), this.to !== undefined ? this.to.buf : Uint8Array.from([]), bigIntToUnpaddedUint8Array(this.value), - bytesToHex(this.feeCurrency), + this.data, this.accessList, hexToBytes(this.feeCurrency), this.v !== undefined From 847b601b7d39a216677cc52c5d387929b76ed549 Mon Sep 17 00:00:00 2001 From: Nicolas Brugneaux Date: Wed, 2 Oct 2024 10:56:50 +0200 Subject: [PATCH 4/9] fix: pin dependencies to a beta release --- bun.lockb | Bin 273192 -> 262016 bytes package.json | 11 +- src/cip64.ts | 1 - src/index.ts | 8 +- src/tests/__snapshots__/index.test.ts.snap | 171 ++++++++++++++++++++- 5 files changed, 182 insertions(+), 9 deletions(-) diff --git a/bun.lockb b/bun.lockb index 98fc081066b8e1d29afbef589981ba73c9d21eb5..b719fc16b94fea636e98a2ce4e3812b8c5877848 100755 GIT binary patch delta 61106 zcmeFacX$-l`~SVWu#lzq-fJiU0)zwtOAUn3K_DP4gg`SWxtxo4?sLE9%$fU?Ip@qmmaKDy zX8c)jQN3E3K`$pPsO>qwy=JjV?MHocuxY{fe;r*Z`n!SE8`Yn7?bES$|H$Fcu_&`| z#q`s2T|UR*D2lD>aLkBzIvjbhQJg4_J&(i|seZ7Jz%O%J-FB zPHIZRXx*Z>+ud`xoU#IX*?&$gc`Z@m15#l&U7q#46xq zJAXMWWzSeet(5N*s;%-0!hPisSWsL_`~lAEx|pHq2`Q7t#W_Bta7A{GX3z=MAZTn{ z%22yte~oY27uKeI)s*MBPJzZHk4_ky;&6OSyH>~FfvtcwZCf9!mY9w$jU9d{S@}oBO`1S9 z$FulqvEid*Qc~iEISShO(uc<+r;H~^MTEKl>Qq8i%v1)oJ&7uk=j2N4k6z6b^7@asYW^}Sq zKc}bGSN6G>*uo7qjEt8rDF49jn&5YQ*F$nSPfD6w$|6HN|19?)a8%JJqtP z-Uh2Xz6n>=*V{HBIY>8mOsj3>TW<4-@d>f<+&v*VE{y;k&N|k8KEbL6<6=_cgGR-r zPg=wU>WgP=`*B^%pKAL_K~@uuj+>y`IO6e@zqf4%V-?u2xVUja3CWHm`?}!?V}}K$ zj&t;_Zw1`hw&Q|EC&tF4ka={%n1q}uj?N8?$?gj2-e9W%m@k6p*Ab2IRnc4xt$=%D zb>9HWuY|qBpd~ruy+#fPy)vUJwjy=|R`bQL2Rw6|2(kYJlTyjFGs7+gahh+s0U)yGHQH2&<5h$%$i!Cyb8kNTG^4Wz0C@=NWHr-MukZ zwR~vY%Uv?vYu6z*At+(&@I*&!e9Y)k1GA60ITYE@#UlUi*&aNeA~Vt9b1kJ;l2!x z8H2Hv@SWJo*eY0!|1YT-)98%DJ+15aV$}jmvCMKaW)oC7?6Aa?xUmyxl_wmIviLi( z3Lus9h1?`Y^fod)^@_Y4ZB=kNR_7N)8^=5q@;uq!D!zMv;|EWTHhue8)rrKadZAb~ z*Mb37wy&|e`%_qz@:OG>gf5Xp`wdK>-o)JymFwpN}Pg3z4U7OUbC04mPEducS( z%2ySuR{s>MVoPE*Vh6`sd>2;N4;@=?B#*2kALsRmOdDodmwlamKHZU;GCYiYj_hly zeE%9;b+}dVMr=t6@^2nYd<8retJd7a6V4)}-A=r29hG2pa~zM@xRiw0@9}-Tg;hHY zO-f9P8Jj-L;g9qw3Q&eISPk4-SlwU+R^zBQRJnX}V>Q0I=I?8}lN&3ab~8;>v&5l^ak{{y!*s&G&kCg+ z)wnKJeb|&Sp#onTW9-dWHht*i$;lIAlEws$OzuCy%8?eIq=Fo2jC6%nd!iL$MXXA& zR%wT0Tv8%4da|Q@njK=|n4pQwH(ybXs{R>PRX&4NMC(~5#Gl6!{fst~30;%KAu=eW z>j0`V;}fig?QXlEby#&~N{kg)pQ*;=g7wp(y1ETk#g9oC6BjgWsAEJTHRWhXx2WQI zu)5t&tioS`)mST!RjHR|SYtDLSSt77bSsK=SVeanE8gNMs~YLGNGRNjSOqXH)tZ|> zoMmMw4A%wUaA6_rr?%aXRXfyWPEo;Cv1%t1F5jL^8Da4(?n51E&sY`kZ+P8veAnmT zaWvKzs@JUaJnMWOte)E6=2|vahIRj2_=+PrIey$I8m9hy>pnH+8+i&>aIMTRY8S4N zUVougi%D2T(G;uZy290pcILCz`HyY?Fjo2AvhBF!(Q0+a7JRiv7FM;2NuD$|c2q*j zOSYeooSc#r7c(X{COK|2!-s*cVP>2vTsi&t^HxpvVl@CZVAXOfv8utdww;MpOsQDK zP#vpSi(qw6-=;G)X>_tRfE@{TzHmEVTpY_yQgTWI+kbJ1uN)(>NYg39ycA&;wzMkScO`a>}rOj6;?#KgwN zjY~;(Jh{@!7n_(kDuLU@(Ak@ZjP%4<7g=;+kAp$SRD z{KMTpoF~3$wVi*|`G>84)cHqQ#ixvnqBYX%uCeaF46CNgz-kb+TWi&$iEXQ3HP{o9 zW0I0$COQ1WWIFj(?~cI~_Mu^P1gwQodRO3=9U#H1A7EMmFF@!Dpq$yQ>OaS>KcYrkVmdfN7aGQZhNc(Z*rX;w!eSI@b^z${QDsPr!vP24zgbjaDUB7pj>Ynfl(QSAID;^ry6o32CQ| zfKuJJjVpD>6*1Bm#SLtqCsGXI*YumamM;G5LuzmiGcYEb;@=+1v zz@Re|zPdlCOqpAsmu+{u`=&Z)THSD7+Hk4d;f|jybS(;6)OF73Z=0Q-Uvgp5*WN1H zu;9xR$CNuZ+1tF{BaX|!bB(ow`rU3L$nVt8Ij`do)hP#c7dS2IM zw{Z;9AeWJ+zSlK2ml1{8n9Inh@Ac#(z{ZN#I8!gw)hf4NFHsm@0J#Bk?NM#qLN-R*cz zo-n!uhr73u8lW?-0(p%*jl8a2d5tK{D|wBKMqcL)<7lInt_t~#JdM4cF3dx1h{NR#Pam4m~A09ven0)}rqJ+suo|+}_TtHv7kz zuaUW{omqpxtr$2S7lx}r2_vex*EOw#k%8G$!Z_C48~Cuqe{T1GZO@i0n*PSuZ1YdC zdDfCy4~Scjd*J7I{z%nm|8%LVRVgEn*XvnO%Hill3Av3kVWFOo($@6hG0udCx*wFG zmPQxmjgjn4dMo95hm0z}V!Si@c zeBPNlp|1RujbrV+p23wJjz&PI(W7;!=XpG3aT;eDg}RPZHZmf-o?2BLj#fUH*(B7H zhNn^GG%~%Rp8a?&@tBFZ-y=I`4&zMIP|tv>R@6C+%toQ^-FQum6HUWCw@HQhuIcf5 zSU@$aa6+sb>Pfdf-|XUk2d|B>a9{I)>i!m_Tvxm5MnU+L4QE>W8}C3p9>(@_Jmgtf~ZPn0k8SS(BkEmWih^K(Tno z@zgJLKI6kv+wyYxuIqrOE}#jRHs|1}6qnl2bI{J2+jp*Z9p2!5=XAdTe|egipT$!z zF)`y^#cP8{xOi0=SZaS?zj&U+vj(Di*R;J{zDfI%?YZT-N(UKvy0gv(G5m~$LE)Zb zr0h9;Z&(11Rn8e|*rcB2IgP?R7D@Gts2*O=>p)e_s`fQJwY2Xk^pvP?owL@Cp?GQ_ zYn54Td%1k!e}Sj)t(+wYz#h~LxxRQ-!)gF7w$ITBH05#IW8l)y&S0zYxC0MZXFT<1 zZbOZ*2v2vg?tTQ%iY2o_SWX(ejgfy|b0wM^T^fdaR*>rByH<0H{svDEr!~{uz#H_J z*N*Bw@t3z0PhI58>HY$*mBF6HQ-NWup+dXxNJZmW9jPwZ7-D4f^?EJ?HQ4j|p0hye zuK<0c+A|!_nr$*8Lp>Yt)GLg;;84#U`y4szgnDZ6^l(>e5PL@8DJM<9NZW#^2J!X0 z=MOxU$+%CbvdmU%WoPGSzIG z@VfuyJ;M7>)3l|CX1>R68mTViDrfWv33YyD%p1_sRVCawHo)r|7;fYl=yfd*H=+i5 z-Dxd!Nq$;$D=DjS6vA(|M|d2uZn=wV= z@$A}d^D7=<(gqD9tWa|M=8g$?sx=!vT4bkv&U&P7x9eO-iR9Rbx(l!8q@V= zd*j$}ugBfND#2>g2s|qWZ8fLhS=H7U+=i!yW7Ufa3$Qa%IL~=a9!9IRdIW{K`{8vr zPBahqyhe)1HNdITEj(-3`UYx8t2i2t$t$*_k&)o_tOx4(U`7iMbzU_*BU^gPML8T` zi+N__(S~?hU5-Q<$3}WRr8_ws-GDS*Y^W=~lMywFb_eQqtl-DOa^iS>{amWE6_c+3 z&j37CioRsIeyy{SG1}|7YC~%(tjNRA-^#*tHwn+0ftlc3A9OLIUTPTtv#PHNu|e0r ziew;-#j|=y=ib2k&uF=4d%p4S@^&-wBzoOTs7P~PSARsxx>RGZ3QsN#NTit*I}%R? zSxe8$cu(Nb@yx*w@N^x0Lnnsy@Gr-ja$dk2#5t-)&L8lIL1l7>Rz0olB6B4<&*SNS zzTKIpVlQiPWBH^SF?d6K*PS7j19-Z-HEc))mJE=BS z3B;J*+q!cu#o==GG4iB%^`4m0((`Fwhkxrt*OuUKuTs3O-qA*$RImGBG#|}q#&Fl_ zr-FH#bj9^Ej-`5C+xr=LCV1U9;XF6(!abGf!Uo)snb#ZY9)%a_+m3D{<@L=v_eg2H z&>KO_+fVxE-!t{Ya^f`b#l27|GSMo$6z_Y|h)VOi9{}4M3mb*IyaSA5fRzI@m7Pcn zcY6jZM5Pi*5hDBEjij3S%HTP0UN=0G8RT?|dV<|IPs8LvM#f~Xr`h1YW=kHj(RhlF zp_&rvc^S{1E!f&#lxHj)5bg=1UuaD|A7P=cg+q)yQyI`ejR-DnPU$g5##FESP>jRT z!dN&p+}&}g-o;NuG!G!5!OiB1UjEYde9wlvVk~7C`FWL3Bo*mv_76z4SIU)dn2|Bv z>ux#B_m~}R9-sszF*!3rKESgdngO96SDaNX>s(_zwWx0bbq~X9>kH~tQo%~OF2wob zZ8V&Dz<26BQhk;3lpbLXBf5j#?~`~veEfA%nh>}J!|QOowW9evcd-OtTh$GB4Jn0FTLvK80ryDz#n~u4FDw8@y+wn5=yTNS*6ed?q;YH(ThdY1dyjRqE_iMKy7eMF z78W~@Gk7eHwpU=ZHL+RO^~JM0G$hos@W0NT`!BEJ7>6UmUy6GeUbwGW4wCApl&joW zwU}$%SR>CIujieyR(tadGO+LAwewxA)p>TJq>fQKpM#fwU z0@zK#@OX%)2c7pXHcidO8&UJTo{{7Kdaj=j%ZXFlHT&GiwjI}MD6O3bP zy`H!UR#DcnaSyMaFGi*{Pv}Iefw>K%Edj5M@0=puh{wW1UB4lv_VP8gt5%wkvE1v5 zNi&WuXRS)}KijP1?u&TVPN>`@|5QO6d-~w1Eod#?3b*3vKCG2*g$3Yf{-A;DhPt~? zrdNFf`vp>}Gqq$+e~734WhBt|9jDkI8~UDh15d@Vyp!`RUQb_6%@{SO8hO?cEGF3N zd1k6K3 zL}B8m8yV}po~U#lVM_C@PwoSF9kfUC1kAABLwy6t(-N<*FIKHoOYqo^D00U4Ej+DT zzG3MJnQ66)wUp1o)BUYi=fimHCiHGVDN#@PhoYJ~15Y`v_4Op4+QwS_3eB=w(Q2t7 zcwaM!ao2$nwe*>QVxyG?gUQgY5R^isW%4EFu z6wVM}CV1EOcvlGvbr;LHs?Qc9k;x+PltW56k`P5a1%+s=48 z+8#rV?d?3gdcH{XSnR@636zfaBcA$__F|tNw8&po-8l|V=cqWd$4h^mVpcnvs*$ChDwrV+K%>)8yf3uL^rJ^n1yI0pRUdH=v*b#vD>81}xQ zFoBeYqqXDNkJrxf7|5;{ERUKpp|r=N1wLsWKtk&o4|r;*>*x#mdjogw#niwz$F(M< zPV_zho=JGYctp?J=LWo1zH^1C^|yHHMA|MY)E&5l>og2KLr7U%Ex!Se7j}m2x5{DV z=kcs!T6MP`&z^Wqd?o7_m8a} z)HMb#h%D?bTJa%0o_)KZP}j}nM#ei{PtXegfMZp5O<7^&dDrXN0klSj0=t9P#P>*6 zUuhiUblgh+5XRE%Q<;5DBXYu;@JVjM!l@YbX>xo@uW#JiS9IVFUl{l!mbCr>2 zjn`A?MXOqjC-#?-c=ahDpK<1BSOAV@SnJ_Gg{OIw$DPem>6ffQWWO2UX%Jbvx%GGq z8}|EOlTxL9+*5P46*;3cHY@-~&kdu5xg--$)nHr@;~~6;zPA5mwQ=lyucyfx>q-V# zr%?A=JU)VC*nCdPo{-)Rb@yCL6dI83CBBq$TqM=qDwqv(?RCD!WYaK&6#H5}nO<$B zn7FPeMP6&-^1f_!CLW)_;dJ$#QnbhL^tf?~w~C+fm^AB$2liiYZS8V9{_}SYBpqGh z`N+Q`*E?lDTJ%9t<8Fh}0k2rS%r=ny&Wm{M$iWgp`Pb}oj2x!Hny+SiHau~7oylo^ zoOTIM*I6@iN?d@A|J*8i>Jgy^W7d$m89*u3_ zv8kXl&nsn>z>HOP!(VgM7A9vrMa3{=SGanEk#XGX`e=i3?6}t*uu&zbspCmmvv3xv zNb)n8n_<2TIM&DPjbFER(yaMB@)Pki^Z1s-!1wV+;1#1$^QdL*V>dh>yy59)zg}{+ z>f!rqyE>b!UgDM18|v!2$;flk>&n_>L}9+&WMp94y2)uB!#7|V0;iO+LSd^^ zc(c`lv=Xy&M?5|9dV$hblWGO$nPCc8fTu37KAL&oK4(o| zIk#9HVm%vPJWXcYis6ug_n+%t$J3(X`{3ABY^(3RXz*4VMq5|UR#Gi|x712fYFoC~ z1kXUcmVcc)h1b^h!UDEiuZ-4v$Q--e^9Q(-Y3Eydj%Bv(7%*N|U7VClf8c$v6n?T%wyYvEcVr=uAB-n%V ztgckb%Ff>WtdHmK9`0$o+u;}tXKH7sw-ztL=jp@5ukjjK*DxEF++($y^K7iVzOu4PRkI&qT%>C7Pb|$}hY{{F*9BsFpGJ5RXkIn3U z=RcWMy8jOUN9McdO4lTBA3KVFY`AgzeR(zOs4a5+Q@Lum-zZqsQ)V4%X&wJZ5X#*9 z-Ty?a#`8DeV>53ebNByk$&a#?tnT<9+rk&d0c%!L%nHGcbo?J-j5|}hX12V_|34P| z<}hDgEeZa7|6|^nb&73!`g{Xty6*afesE;Bh4JH%N=iT~X(Up#qis7Dt0TKrccmcN z$w=2tLAq|5?N7HYH}~D&_fr?lMj9J)kp^C-?Z1FkAWKnRv<|7svXBa9QS%+yt@5)- z_=W=$n(vTRxr`X!@s94Sj0aIwbi;@L+v)~4ZT?SIfq!S`lU2>XN4owt(vjWj{2i{}JiPZgu`X()pi}4q5RBNcP zWG>r(oK?*|cD_7zK3TPF0o#9^<_wI(ELg zc0O4pgKS&R>3i1Lcmp)xn_~5Vw8RErJ785%N30H6C8KQH$+n#ZIb?NxPurK(1JoDm zGFE+FQU9vWF~B~X-3krlhwLExe0HlShQL)?oNY(i`D8T)#$tsM`Jw#dZ9fTH3IBPg zJr9uZWq1LrLsorgVuhC4c9|RwSrxd#_8(^zz)N<%HCSa`Yx^(T{(8-WI`N7PUX{Zk zs~fzARY99%b~&DZ`)*ad9I>clSF-)$EttK=Tr&u$gSTQ<*b zRnC5!%PRSf?aL~e{;r)kV4uitHF6Ha)dI)ud>`8RvRmEgl+9(8|6{Di#s!;ax61z+ zoDrSw_>zS3=vSY0$f`y+Z2mP?>*{UWzhm3GSRJxT-m`sK-S}s$u6tzLoD?dqfAlL} z2n^iuqxTYIl!nUeJ zOHRnPvM-cXSG2eN>{ck!=CZo3qwPP=>QpCwDBx~b-*l&hj_g*b2S3zgeX#PQ^~1JG z_P70ivU$iijC{&EoFAIS#$pv{qKn^NQ&S}AtZkJ{u`{H~F&e#6B;p z{6%eFR>=~!|3BDtUj{{3o{TD>0#<=kvM-bsuWb9-t#}ptd{z6rtZH5ls~R`7&o{Dd zW2_EY-&7T116dW=#P($sSPPqbZT>i`>soSNfw#8vx3O(o`?~B_`69&i{P_}pvpN^a z4~^EYSlyr-R=lTv{0~;6zc1%?gMM~C*<$!(Y(Km8EtO;K6S7K<=ZBu>$ynWZilA*( z@HE?()%oeRFDpOYwllEmf~T?kam>+=|F*vQ$9F;n&$BaRw<<6LuJa4*^VzM?b2k5f zZ>{_L3aCgyZ%~kKxY;i7e`8g{ZFc_0S$$;ku6!S#{vd+_`O_}&aaK2UD$2iEUFU+!=CEx}tg;61LxB{OqvuZvff7DoSzTDt_W#K$ zfYNrp>{h%iT(&$`TbDXm)uo=DUp9xvU$6~i^}L7LzN`WXv;FK=1vi7Mz!tV`W#?~g z=g)3cP8<7tTl>6h57j)%2C^!+v+Y05>W1Cyd_Ax#xF=SZ^x;PiSzQ%t^T%18A7-DI)zBS>)kY@`t0*U9RsJljqI$;mpTp|d*X?|pZMzk#a<| zP+lyj90jpz>XKOgILh%u`Kx1dZku*K^xu!VtcE&Bqf|vVkdEwDL*%B9{Qdv>r6tr(|9;eEEeZdA)b;O2UH^X6_3uYr|9;fv`1hl( z?4N9DvHbU=F2}zgb^ZHMmp&u=_oFUN2>*W6rH{Py{_sy9ajB(rUazy+KjIRXFaGaG zUH^X6rSV{W_VxdtkGjlhF6X#bUEg~4_eIaYw{F_U9Xl;Zojtj6MDX*GmGg`opY>>R zP|Mke57a!8Yu@muqFPlcI_$mebzePSf0t+GEMr%rEyeS`QT)!kyMl5!16}C_s>gm= zbbM^k%JXAJw>)tB!SBz7M5N}*+2UlyS^W9(0=ciZx^f3 zb>;qC&o8O|d13b`?kvUVXON4oNa?q>-)?{FP~i>)njPmBfqa)9&_-m!c}Xgc3D}z=hshk8C+)9q1TVKYF_cg=VnMj z=Qy)>A!jFNO><2lXJ0e2kTbvOF6`{orIx?W*qnjEbu0At{t2Y)FTQe(xVNhN<+k*D?fVws%>-!X3$ za+c~mdR);ht40rN^s%?rC!J<5{_y4tBewLuFlO4$r+W3j8*=;DkYam^H!NAJ+@>wD zw?E9=t9anvd`&mjekymFrIkLc+kC=|Y@JfabQU4ptipsFSA_V3%q;@ZMF7Q%0_vMF zMF9ato%z#4omY-D{O--HZ%0k(a&OSQdbMLZeEVW~_ldV>wSS@Ju*6ro&sZ=l>#Gkc z-#XfG=y^xz+Bp>$l(=(lb=|FvE*EOkyi)&cHxAC;EL$T}GGmrMTKm%bakXaG-;lXH zaNy66URd(#{?EU3cYG)E!jCN%_RZaFS?QPeRy-2YBX#4~1>1Mqe#MdRmA8K%7xzun z)<@>1qRvugYBAz%WF9C+yz#}TK=tB)5OaKSK&j$@vw$w4*>64ma?52oew`D2set!x z(<&vlcr&}Nxs*ODc=g5mRVvp$JN3<>=imSKl}Zf@-064l$nB-;N*?{D@tUTCzTLWP zcS7)231!WF#hsp%WF zXV{p}zRoxEV3m^d+f18rvcwyA7M6@I)vbaf|K}S^XKR?I*`rJTy~zi0ORo=~?6?t< zYyB_PX6K&XyVB8o>78d?D6+f4H|q{Zez_>3O zx;}rl<kn;`(YyT$P?(x-5zQV{5CnC;PO1 z>+a7%2dk!jpK9#xnqx^zNB6s12UbaX?W3Yg-oKSCJpK*#Uq{Ydk+UzDracU6wV>*o)>c6H9zgA+a++4`Hc&D+18ExZ^PtV;Q z6}E8j=8hYyE^ko1`;y>BJFk0d?|F1;rba9?1c*}6L5g24LffWhWHfw@%yy=wqs z%r!LtVbuWcnt)idM@_&@fgJ*IrZW(*v^pRz5HP~rA`n>vP`nl(!HlT|cpz{{V3b+7 zHXy4eAhkANjCnvHIuKC34j|DSUk4CS3vgCoyji&}V7I{Rx`1T!j6i&CKu8cE)tngw zC{+h=U0|XaTn}(WU~xUbB=f33T3tXyeZUkmvpyg&2ykCun%TMm;DW&V27q+)p1|CC zfZoA?ndX{cKv;c%yCGnf*`p!groaw?*`~7*U}*zDTqD37bBjP^Frav2z&taiG2nr~ zA%Xd3;SfMpLqKW>V4-XOR%w~YVFu;9*Rc7mOzy*Qz;eeOS zdjfNt0(v(GtTER#2ZS{PxLW|$nLSznZVK!WSZ_MLfTiJpI4|H;bBjP^b3pNyfY;2J zmVgHWhXgj7ga78r&GD@P0WAS%1-6)#+W>Y8%x(kNW}Xp< zZv_Zx3)o@KYzrvW8gN};ml@m+a718nJHQ_Esz6#BKtu%KEi*F$5ZD%QUtpivx;@~6 z!20%pcg%YNbK3!WcK{qP*K`1cMF8B9fP-d_NWe{j9Ri0;XGg%&_JFvKfWzh%fyfSk z;!%L3W=s^|fxsbw<7Qz!-dT}=RHhT>3G;wJbVoq-&VW zflFrV9)Jr1>w5q$oA(6fb_4Y83Ak#m=?Mty4siDZd};RR1-L1&L*TmUd;+kv2O#bV zz}My$fykbK;=KXim@&Np4+IVgd}kK!1IX$HNbLi-WgZZSegaUvFW`11Z>Pt{F(dVNU|wg8(_q z9)kck1$GFyP3K_1(gA?D!GPT67J&(qaJ-!vST@%;A8*VSxJr<;~V302c(-j{sCO?+MI}1N4puR5sVd1Hy&_ z+zEiHW{(8GO@SQ()lKI}z|s+bxRHRG<`#j-ctG({fLdnED8K`OLjrZo!lMCM34qkm zfFSdLK=epJ^)Z0@=J+vyfKh<60>NhGv4GtIv&RA&nP&vzM*~6<0U_qhL_n!Afa?OG zX7D(`5rM_y08P!S0%>Cb5#s^jX6AT6U?SkYKnt^V65xWs`XoS0^Pa%mae&^*fY#=k zWI)(>fI9`y*6fi2xGAthAi{K}0+uEL;!*(}%q;?u$$;V$03FSk34jLzhXgvAg(m{C zQUIwF0bR@k0@0~}>S=&(=J+%~zy!cqfgWb%Nr2q~vnK(1nP&vzCjvqy1A3b?Cj&~Q z0j>-5HG`+{MfWXOs`vL>a*3$qN1lCUj3^wlx%$)-0 zJsl8Zu9*%9n+kBJ17gh{>42L8I|SlP=M2EoX@IyHfDz^vfyn8A;xhpWX3R{$1A#*V zqs+oj0kYBosZRmMmMInP%oHz;1#20*2Z8 zML_&Q!1@;fi_LoirJe=!ehFZjYhD5z5xB0)|qQI0B#DnHv-n1JvIWC8h{-FubR%+ z0g*2N;$8>5W^NI9AW(c0V51qc36QlIa7bX2S@;b=^b$bo8-UH`0f7J$P<=CCi#dKX zV7I_ofo*2xHv#cW0khu(>@d#=lv)M|*#g*Q&fEexB5++`j~TobkhUDKcq_}tTTb)Z zRxL3rASaeW_BqXF+qA@ptl9>7$7y~mGIu4U%XY{Cr@4GPBy1Jrk;p-(8MOm)Q)JT) z$RVfstH{z9Ap>_p4m-^aJ0X!TLGtf{9Ce!gcR?PA>=QZeH1q6+WUYpb*$p}2H1~=` zuYr``13Be1NA7_Htc9EqIpZ|T?1k(WnYI`5vC}*z62A@-^cLi-)13Skq}0ohOCsl; zX6?5jM?@CB4f)h*UKB}N4{5Ov@|n}j*ar!G1#(N|6791eazSL(e#m9oM`Z4+kS^~) zuF^j5K*F*hk3_ztecpxK6xsAHs<{;!2?IRNXI;8yjkUO-``;dT5kP{;JXrDun-6GQtL4KrtMB?9o1bqOx zPy2iTDYY4LN#qyW=P=}m$il;rhqRAK+MAFTM={Ue`J``BG9Wd}iKyLH34*`)o0QpY< zJZ8TWfCmEm1oE1mlYp$9fH5Zl`OQ57(Yr{MKLsdgCY%BU>;{|=C~THK4cIL(?KGgM zc~l^N4`AS8VlVD8N3J9GQhRmHI!H;ES>|QP5s{!XTvXbebcT!4-U3__C~MaG2oU%- zVBtrA^5&-k7X(^-45(<%`xr2HAK;ciWwYrgfUy05Ri6N=n%@ZA6zFmmP~BX17O?ak zz$1a0X2)}Y$aevYGXb^CH3AO=+~)yx%pT_fSqA_+1cFTG1wizBfVc~Q`sNmafP;YI zp8|r-m`?$_1r7-`G7Db>#J>+ny$A>~4+xYx1gQQQAk-ZH8Q_S(S%Icz<<9|W9{^^5 z4hT2T2m~Gmgj@o&FlSx@To5>9(x@$6X2VPkkt2{>RL0fXW&ZjCBsU}jzhL>>p+7wBlVz5;k4u>K05lX*`d>q9{AtAH-%nyY~5 z69D%$KsU3;H9){gzz%^Prt?d{Zh^Qj0lmyE0`aE+#lHgdHes-Ub9-0>s@0Of$FKrbA9&au!dY zk-yLQq&*d08J{(I>)M4KB6fz3Y`&&#tqyVR#~ppqQSz&KBR`D1zogQI!naz^kA3m8 z*M|(q-|fK2fPPoDRlEI5_de&ceZ;0;uJRu_M@27Ka;f?3yA#?tN7sLO%=q*5H`JOo z;=Q}Qnr>SA#QeN7-t3q2mD%0CC_N$IspQ@_kNno{vw>57*|+?Cj=&PG(sb!B_*&ZB0$8k@Y#nf3H%V~*zi zXzz%uiV~nL9RHc>47^|B>_bs7mR5i}xG2KWWbN{b@}`XPhs4 z=w9FucVxAy88w%zO3vDR>d>;=Q%c`FH{|1=PFI~YZHni{usaQ&n_RcW(&skctp2ST zbeZs+T?co6V`i><@%yGPf3!FFc!qQ1cdPHNzgK1R#S891Ij(H(`o-F6pLAJy{r6ZS z`ToqAVG;WWmpwcDz~ZMn{V~7Q*@$f6&B`9$`r%u@8JQGy@L}(vd%BiBUm*D7L)-4W zw&Kxmeb&vbT<6s3@Tkkp4xA$IY00cj?0?n@wAFb8?N|Q_M>W zZ`i?=yDn}yQv2$d#2e*T6`a4*c;Z$;SB)ndmj8bJ3x#fvcxJ%20pZ{0-Cm{Q$~n_p z=hM?3&%a&#Peb#ww(1F>dpZsIjpSLS-TR*yF%HrNrvfjRz^2hO6(L4T#HWywY zyo;Z87=8Dduy5`*Ui)Kgda%|F%{o|fA6P~Yd^HTDtwuM?IUO(bBTU;f) z-=7Ifdh66zw+@~^G{5fYt)X#0xYv)~e{tybMss>R=#b_-x4qHDyk)EPxzTNGQu($I zH}rbD*H2&GjE#Hq#n>Dx3s$p!so(k=#Ch4nTV5vL&-asqruBHe_}3j=#izW`bo=u? z=1txAeV5Bwv-015duWdfFD<+He(BK#1)%R^0u2evJ+uu!hDrO&nbah7>Y z;SH^~snfZAgDxMQ`FoB6KMw2Ar_;BtA3xo@w&;~b#n#7rZxnm$jorP%Kx~ zo=&6glvop2Wm>CIwI+^_Et@bkAzSOs&mLaK!;d!aDU?yZ{II@n?ul4Ab5)5eCDsMh zD){Wa?Quu<{g8J;e9;$1yj;EXy?ISC-66Xd9;wx>(fJ<^HCWny4` zlDJZVW!w{!Yk;ht^kp>vZCs!JoWva8%ihD|sF| zzP+^e{_zr1-f~r}oUfg6IA`N*;VsM_-l)&EU0eEU*{@1A9NcWiyPM7o8Qiem9QF;A|&PoIi9J80HJ&r6r~ zzn8S~>8B4I@3Ldx!RMF8?EZ)G;iK>7Al}S@V`#$Kb>}T%D=1L56&A-v-?lZ0dBJ-zei#Q|KM!t z%iZ9C5Q<|Ac3F zcm45)bF$O5q3Vvwu4^vW^3J;k<#6?Jxqt4>uNWzgI=Y~;zvO&;cMrd6JwugEic3x$ zJt58!1E~`6 zHz?(*=5n{=D_ZjGB8*e~2UhiR?y6hPwaBFkclWvPR&X_Us{Pc^Id@ia-OZ^oW>8W! z*N|y>O4$$f_UFyXS+1_>wTPQh@z)_=RgwI>j-5xpgreW{(NWiC`b{AHR*;S$n<Sqm6{d|z^Q)MoyF z%$yf~%x10ZYxP@U$8FZyX8Ok`r+kcGzG`C^sEAM78Qa+z74aFHMcAwm>?51$3jq|M ze(~yKn{}{R5!jQYb?6HMlq`yd+UY2)@0Y*yYqzmF%hA<7S)8>0YYw`@bdwUOhMiAe z5TGQ_k)x)~dSR8X6iQZt;|ZJbY&j;_thdd|z|zxfsBaojvMicvv%WSf2b*TIXq%OX z&9GTNn^l0#w3)t{KuP^8LaoR;)EY`wLUSyZ?igUh%D_bybPTjv6_~!tM8_bTF&j7z zA+`2k7=Ikq&_$#p#?Dur^fe!`nq0-yK+BK@tXe#WezmhEj(=F|dlHl}5XIU3IRd89 ztAAKB+-76!e6?YtVe0F#F#b50h8$yUHqK^sVfsBg9s0@z-6IH9NVj3K4eJ4`+RXnC z)a%0nZKm&K(8YYQo9`PKFpdc}(?9W;Mq0;2tdg2~r<2gYn}pT1jgWS|V(I!C2f@Z@ zh7G6KECd!uS_5>d&6<$b;M1X->012*4-GyIP~A){41J&khi=9neS@98dB#y0t9>nh z(jCokY5~=++D+;j{iBE4HhbD;e9fQZ52QoeI_1;9KKK(=L(kaEOIrV(ppH2kOD?t~N;D6`{V?ny!3p(LT~Tp0!y!((l+zi>t1U zK;tP-W8!%`UwhIMU^)ynjSB35Cfe`?n?=I(-`?q1Y_pD}^*h2kme?$cbZ(oOHtPht zPg;k*aYMm$M*0c}jgu8volftmy(dKBqa*jH`FGVIVUQQehgvwo!CC*2PFn*Xak`s3(#zIFJ&U*t*B`Cw|^ja;B6 z9DsgQg5wRlz=5P6*laV5Kl&df91oP>(D#lgIT-y)LS3^Bt5tFc#gW#y(4j%A@`j^Bq;-GCejAP; zU4|N~H8he{sd(i7vWxfZdsP+DMbeh&19SvwE2OQDwmKi8 z6G&Se?P#=v(T+ts6s^HpatES8XfPUrv~0$rYN$G@foh_Ps1mA-^zC76EYcnNXQru0 zJBo=&n}|thGMa+4fzXCwI+}sBDR>IaLfQ=IJ>(grO~5>qf#xIqi>ig_S@ayzejpQR z4{(rHcprVBK08d}2s(<6q2uU7bON13r_gD127QD+MxUUw=o~taE}&1*Mf4f^99=?R zpv&kAx{9u$FVR;>->)`GUx)H8j-Ew5XPU~2pjAjuwSFPK8q#mtUq;`cZ_#aZ4(YoJ zw7Jk`Vg!muqmaHKp%>Cd;Y03m0-Z$qZiot~BC3SaEAyiY(ng^gs*Y-)nn)XkTBtV4 zft*Nd{4`VtY2RKC)kh6bFlvMvqb4X6X??GPsv>>+SW#>#R0fsPGn<2izWwVv^aZ+x z4xsmu7JYpe+S_P5+JRm{E72(|6KP zZ=-!^9a^h2_0&YDWiY0zVD(fYKJ0Fd(;6%qK>FBYK`>8 z9L-UE#EPEo$Vnm>%8h>Frdqy7Ag#m+NUN{*ogGmWYK2;(b|?aEqAqWsmZZZ`bJPO$ zLz@c%!S{g@6auD z8|jxw0+0vgMfyL43!oo3r-k_^bRYeUenDE8AEIBi)&Gse@8}WwnHy_`{tf+(9-%*x z7QIw#GD<|9QCAd+Hd8q-R;z`UtbX`+&_MJqT85S*H~N9|+5>5O(+q_>%>8>@Mbh1YO;iJn5**lEGOiM~Z&A+4YK4VzM^AS!}<-*$u5`W%MBk$!tm--=TY z)kjgN6Y7Ha7OZsNf?NitEOH_j%7L^fyHPHb8>MhV{R8rvs1X%tf!d&FxZzx+tH%HV)%aGD<-c&_tAmCZWRw za8lFEP;NYzW6>a-rPlKEYl^XB9Nshjt>p zNhTt_JnCifPXfDv=A-A(BIF{N?c8`5+Ku+=QQME+LFymzK7I&5n!l@|HYgMYqXwup z@?Tenv_gGbNf1z#d z^N+i^ZmLF(Kzq;{v>K^9$D;*Eb5U&c6>PH5k(x1m4D`v-c2enUT^AJ8}GJM=BO ziLRl`DE$k5Ttc6tGw3)vhSYQi(7Wg$dJi2&htT_I7Wx1kMMu!{=wqaQ{t&5^PN0+M z6cRs;bdQg0{}VOZXE^84Idm3%iY}mwNawDiD|Y&8>~-`d`U>4Zs@Yt02i-#7qub~% zx`#9l9w4>iujnEA2`R7#>a<@-=;Y7n?>EdInDVGu)og0D-;tlGnU(f;g^R9GUNyP$ zYl+Z1rI^YTSN;Hf79gkswCz{39YFp!SP#sXFO1Rt>4idY~$#E1>eI9Mb!|u2WjJGPV-Z>wRJT zs#tCB^bS%PUu9@hQyqy1>MI5VN$6d^9@342ZNEO&UvLxBAxQ80{$Ty*!eF5&kZT9I zSOd^>d=0urr1dF?KK<$hYmT&|YJobUNcF$=b`hvGYKh3}@M7KAR@mxTv38`}pth(z zlCNtbkqUeYH7DN;>`WAk#5*G~zpnw`1z*9W>!n?Z?nrO*x}X~plO2j;&;T?94MKYB z>W>DZo=E5XOu_Un9+UISJ{$lND_pqMK%esn`&Fe_yEdI`OVT9J1t_Gx6ICCEU}p=VM0LVnCf^Uz#02R(!4qYShFWujVW5qch} zkj3Z)vw?=ag>^+Jjz4JJtW2NbEq{(MI$#dJVmb)}dF>dZbp- zIaw)-^aivIy@@s>?U+>F8%Q@$dJEc$Q~^m9*o}6f&ouvE<)SM{qqG=JSri>0y$`*O z)O7EnchG*6lk+#R?<2L`d*~oit9*@apzG)>^d-86uA<9GUGoJ}t9*_=Q~zH?7mx

3H054HXk`v>|Fsm7`3cT|LPg-}7HH|`%`57GbA+;xCeadd6&E+`fh z0jXE2VgrN=TtNkULqsgt8z>4^1jHJ^Zfr3odW;gIvBr*#SUxqz#4k#Wy=yFqY4)gz z{eREyEcM@OQ{J43H ziu)+{Q0}7KLHP~kSCn5+xB+*{gqbK4dxN4e^a}SHGcRzjbzZbn?&GOwU9m%W?jb^Pp_(?Qo4kX@wHT`frY#W+;&;MihRLFb0T8DC~}$ z+DXPekd>DUe9viVEk)e`_u(iBV2tZDDRF9>aU0|61y~bYnNeo01+FboA|&WvBh(fZ zZBSaHB%lFz!uRb_G=_MI&VNie4)tA7Vo`#D&$*{gDE#)LH%c!QR@EfH4x#kKJ*RxS zp>W!#2TC8-|2rt0h8c!31SJ_IlRH48wzv*J;d#9u>f4Fu2wYj5{ZZGR;V7{vF(?d+ zM|}ccQF^2FM;U;+zPR>6>4}nn=PV7#m5HL!KwPzkB^xmQpdxUMn1;{KNq}<)9Z?43 zp6PKr4VOFSd!&N0l;jhyaE7CD6bdJsMxu-mS4+UOXTBee`gD{uab@W>M?Fh#BFY4m z@hB{vak#Q1$KpB$g{8&P;b$Y-jA#9`Xx~G{Oq59|lTor!=Av*WZ8pjjlo=?qQ0Aaa zN128)6@^u(wd1Lr+wwCPzV|^Lx5s}L-YC2n(O}$vL1RW{L?+Bc*{DKFzzuk2hKn+* zF{jn>Gk2g3L>mAzuhD*2;ACk?z9l+hBHF^UC^4=t$pACX(qb5^BGLpcGg7XpG-8pq zEHNq;ca!b-AO41f)7NLEM&(#%Hjrv_s&Gznaf`$`McG} zPF|`Y>8w!WftnV$Vo#FY@cZ4(>gR2JCh3AuV~-k+bWAOFQ{9tIZtJc}x;O#(K|uPt zy57Cw)}q%vN%sw^+<;sTl7S^<+kNmw-;)_XJdyCVg9_oG$t(RS0n`rUn}{zB8Vy!hJ7e&Fl>H{7|IUrwS&I-duyk6%IS&Y8Cc!mm;n}uup0DWywX7%aZ41$yusV zh8kR!45C^eV676aaPjfN?z<|CDr}x>O$V<)-o?o*D?<-JCiF|RW3zjZH*@|+)<1?R z?F?)m)yt{oeO7<)O6MJiR|$%UK_)5DtSgeMJ`9bVLGIH^i+7KnySItbD3EPNupx<# zr9!rBu1dlB#jtr-G~7G(*Nzujy=p8P!muFZ-d7>y6A&^xY3Biz&ehH7n^%YdAvN2fzN zkAH8Gbb|%tV_YGo?2kq-no%kBxtFAyEFk{?<5@*~{|k`C@UmAff4ymX+ip&hZjI>Z zX94*&y^JNr-@7I0z7>$l5HXwK@r1`?FC~vXA?Y3qhKXGLX-!c34!Ok|uQk2VmFmsU}ZGBSU~OAjn|x)RsCRy+O*~m%Yvx$_r_{!s9B~w@$Jc(qGn!2i2hmsjqqP2`b+1kQc9rgoMnC*FwcJp zTP|YCe?#-d6_15rHZA`dN4Ea2gg<`dKqXH38*lyAxXJaYOkOO{8FExyFjsheo zzz`6I&8sV2VMgi!1JiN#Pn*ZR-|gn8KY$_DLCsvr_92GZ6&SodetgNN>Wa^9@roX7 zF!dn5bp4@JN2;QyijO2uO?AePtEn5jc2_3(M3jBj7A>*Q3BZ2Fh_0|C z%k7ZyV}+ZTfaH(G?CT5#GMvB0&QncI{HY8*3a`)RXDu1d&2q;6FNvbmNA&H zi1s4G?^w{;cvJT8kW)4I8Y^r@+1kt6uiVBm=6!HD5_{gX<9BI^6ybx9D?wW`v9><6 z4A1&O)zy{w2Cwd)KA-lcx)>>BkXD`UJO)>~8dT;9Fn_3_ZYUOi*yQk;&$|PFJ$^77 z1!U3X31m^zm$IKop8T73Pq2sF=u7*afWSdtI>!W>)m90_AM*OD^FG$C-towwB3M~P%tM5;s9aa+Wt+}f@Xs^)&PW!57I^3YoK8? zj}cu@RZQ28$714bcN{@m_CD~_tseRPDMcHjanIgYZ*Ank+tU*8bK5XW#pv5X3f%9| zh!1CuI(>!PhN_U@Alm#Vc#jOCfB%WGlrhjtevUJc<1@+N_7I}x9o^v`fq#^rv+F&D zVR!OTpb z`ZVtqqT)(8GeCG!t)qtTuz=Wv8ic-|4Daa5|nm|qDUSSN`)=(XyO!mL?kN@f#+c&^L2PaN{ zBN@scZJ=VfG^DL>Ai;@tD(fqcEgtvDkWwS^(C85D?Zk!tJj*XudgcV|R6AO`3N zfn3`#ooz_jHnOws*1{m!Mbb4|7>#|FH`23gjPc8-)Nl5U^99HP3SlQ|*l1xk5ZVI) zoo3%ZA9Xq9-cz{{p6nu){6$7#}9`-thtACH^S-mHKOBS z!0i|?*bF+I&po{CL|1PG1Fnm=qSQeryFlVWHnNMpLWG(&*k|`s&0qXtcPe;_s`U}{ zpfdUj0tRO=mSyboPd;Up3XJ+{nm00nPU+-9Qrie>AjwPg-GRxmIr{0t5m(;J_!5{R zcp<_*kYs~?ATT&se0iaXl;`oJ9WdB9!PUqJij={(iOF09jR!PJhD^sq(i|Wv5mT0< zr89Nuu`C;;tj1K!63=Q}a+bz6q4}1;Q*F8`9k7(^>rI3+He2+sHmge!R&qm)hJHjd z)ykJf-H7=td+;7bIEvy9Hlxi}=lNf|^2R&TJd#UR1O0s zrc)LPqOqkl#&))$Dh0>a-YpMoIXw>;YydbWkQhb7tYIS0VQf`EJAKc zcJPoEMaw}$f`8ltrqMjDGVRm_P{s8pPBgI0NdgT};GhqQH7ZwJf{?vG<&~2?gaVu; z&GA&Trt0P8m=bl8Flep%Z#dJ=_GDWD-YkeVs~{(7_lGOUAsQt&^Zu*0)VkLFOz{7bg{#?Y@Cf4OiMwvNgQ4GOZ0RegNh*FWf8@9gZZii{N_ zr17^Iqg|C`S8X^VY)NWxlKwiP6d&YYM>99`;j1_)l`SDHOGv8(*u8S0mjAk2{Ah8J z$R~7S5DG0Aya>sQJ1OrIv-fnX^K<&E26l>Ul_iLX!6vCWOM5!eV_O*Okxo>r3JhOF zKDVk})IDNK#i1wU2{-WS3g)fEV|7e)rHbsT-vumQGJV*t+^FUYzZ#?HTIqGGE!o+@ zT_f?{8k_IzAz!tdv+H=uG6h4~c6EuP{&sNe!ErR+POc-JkE1nqvZpa0t7xYANsVm3 zy3-O9Y<0Im!xlC5yQ*#*we!vOYrU`YzJWJRu&g#+=_PuTx^<;MdqjAwr5D@FOPos6 z>JJ(pQbQ-Xnu(6;c2f@XX3y!aMv#?5GDeSk-K!cpLM-A1@sjS8;{c{tb*Ehpm_ke} zurL{MB#G@w!>R(aS5KN=6)a8eP51bDPH(bylnuIT)X)*GC8~8l(MU%**r7DTb-U3n zM|p$^$dJAi<|KQXfaLb2VNP-b;|n3m(r+fc;>G6TVC&Usm51bFgkqN(5KmW}z-M?o z<#-{LTFF`VlUl}8BWJmblpIfKH7Z_B^DezUmW zO49KZkCmB4#RLj)L1b_O22T*%``SCSn(jM|-zP$W!0-WtHT-Sdl3E9bob(4f$SgAm z?^Y(Fty?fK*p3#Q$V@m9SsCv#l&Avo`)P{{76unZ_k+LiS(tJ8jJkkO76v6>(>S`q za{CQXdmLZ;{x2uIK8NMhsm6N28 zD^aXlfe@s$$~4stHdvw>GszubNj`&Ut1qrXg!+ktR0kXG)M)I?te;O}K%sCj1Px8d zG>As9ur~~%*jk1CINXe2j zQGY*NCj;z{>(V4TSPfI+rX+Py`RK@nN}I~h*s8FjC`Thyq9rwPhYX^UX}!Cgjo(JE z>mj?iMJ20~;&&enjYyjHe1^~x+~E%O^N@qhAwcd5f=dB^T5lzLSDy`~hAHrAt0yLg zk}@bUb}?q5OrGl%4Sh0vQG#663d{=IFR3$W!*Kf53n~_(H2*{9Y=1efJRiMS$>v7JI6V zDYTzy>`I|WK9~snN98rCF6(s?0DWr|5~uYwAYsk;D2=YyK#%5Mi}|IiE4!|_J3_6G zjjD$pafX0XNrHyHJ}{iY(}m3NYhI0i|61V|D>fuk#A}@rE~UAWs4h^Ga1?TN1BXJZ zbf=M==a!*{rh53D=f20{IcvtLpCF?}bO!B@z~Dr#oXSTcHuMBKFGd|Ig=X~Ly+=9F zp)LD_>>MK~xz}iasiyTa#<4OJS4 ztQxFHN{L!3L(YaXz^H=0I!;ObI%-|7vxOKx0>ajFb<(on>&6M^0Z}$})F@J(s_!~c z9rAB?>BFIa43m_020s0OFnA>rJgDI?TThv)1;wAcajMM38y$fuwnQs4X>(_AxgQw3 zLXYl*5GWoe$7EQ#n-hiY!ThX5zuS}gB8a5Lx#f-Kzi?%Yx zE?}@)>z$ePbiDPMi@;$22`RKQjkacY+VyHSMK?7qf2IJwt4yYB#_*V|T3W4#*Y2k| zJ;+n|S1@W%rX5WoM_L<oNhOyJt_mB8zjYNl3y$Ebs88fY}><|zWeeOy#fZWW+9gAGpRo?OoYr#u^_mMwwyXz z9{T>K9p6>VRK}!is$a~c&D^&9yQ+EDYOp;lBd+(qAT{O`{ks5y989*`ew&E9k24RU ztw=kSnME(rR?3-0nXR$R3TTb3f%*`wdq$Jm$PV;KH3Z+b*Q` zTEp|R;Lmq9#Q;NX8RIFny0o5j@y%b=5P?FQbj0$J&Z77RCn59 zR1j06C}eOl^14RJLv)he0vZtuGHwg#N;@d$6^w@c((mZmJDX0}w`2y8rh?JcSU|Q& zNJ)VUNZ$e1h70ImM_fU^FY1l07N{+|-nbXCsa3#2bx_c%MMpr`B;5M{{{GZnj;Z)1am=NR=Oa?~*D2)i*aDh}w%S-| zb9?xqCK@qta*UBrl&mZz4Rs`gB*6`x=zw^!Y!Th*AZM3qEJR3qVnG=>ojEMelJf1i zfG%~!{8JL{yo7pp!ZOdaXBt8*<}IQ5oj_1M_NJXV)6RSuFD+3e*>YU7C40YUsZOle zR|Q!lFIB_9gvaN?vo@q4H6SvM7O6|gud~@cgF`HO5pK-Pjs|?*kxluSNA>?{=2#Smi0!w6cEuq9n7TrBt@S5*oGpLUZmtrElz5mw zMRlQ?x>c>l?~Ht;K$K}ca|O9~MJKb+R#^z#wd&r~_ka-?9PJS)KUzVZx+2yf#!T;u z#jf|K>T=~+!&VJx!fGsbGYezOJ^U3OG z^@a08V%j|Axk`=8+vNOp)hc#hpm3^0?BG?Df|*RrEmb|x$PCk1pNdJ@xN^0+m%IAH zCTdRSf!ifr9cYLDP66TpCf~D*8r*!+AxxxeuQ=dC zbf&SwtFejpn5{8w~V;t;F#VV4{zWXsOq) zRYPsNnQhj8yKUaALVW=9dJhDP+_eFJOg6&rV!od8`|N41peaoLJ3x3O=ic?I zIK%sS4MqFPAn`7AVozva^+=O^3GEBM98D-CIKW8rgJrjH$fmS$V7fG89Lhwh8plQh z0?Eyu*w~8E=uPk}ma5SkD7zOV(|d#J4_&gdJHPz2GhV-F1l3VFQ+_W5;!jY%B{i0AEz1 z?3$39w$&`y@0!fXxGe`Gb{KAW%LON=yuWxU7~y0Ng!Z4aGWz>yXpe@|lZV(>Xu6Y+ zlZL7}u@X58Eng#Tr^q^BOv{UC=^c^(aLd`Qo}5S;HpR*2$#dQS3W6#p`aM8k_x$m- z`?YdwPv;aO{6*Hp3{&f31dKa zT<|Xz;$sPWitI0!(eDQ``-<_<0sZB&&(RSdcYrfloZm(L`y=zWpEjY9xlbj4sUqml zgE3oBdiX{6BdMtmyDAf(l7rC8bhAGqMWxTx+2`I*^0~{ioOm0-hjI}8yg#SFc!<HAq0W^0(l4|7;ynTu zLPpKmqZ8ol!gIAu?T!Svxi}W=Y)aDH2hG1GIb;RyRcG&Y5jMsXfI-t_0=6nRC=*dNKa$jSi^f}K+ z(WvxMyB-2k`sBVQxq?%{1!qIkMH>?*_umts(&^Rp0`fNEHlLzY6;bTGuqFlb9hrxe z&}$L3nwY1>`Wz~9QPxIQ%%J(Os}jTi2RZ$hmK2Hv8~v4>%+KfI z=)8%~CH^;RE)ni!zOw`cKJzEN80fPiFj86XeN8s(^NI;Vz(=Ih2* zdYzb-5}%ruXp!G6a?gv_y$+6Ut}cH6J!{*`FJn8dnTBURM{+BDa8SxiM>za%To+XLfJ=fzRsH zTs(97<4w--fcx`Z9v%?z1BqL`${hRQ!8Zba>w5gW-I0TG&*PbM*tgDi*%v#g&zxbm zP{GUl)gBA2rq*sbW^nw7_yI|Y7HihN)8>sw`4+)QEiruh@#h|UR_pAWF&};<)8&D34f_ymV}kq#CT0W-7!V#FX29ZPQKDQI|8k>WqP)%l3wCT3 zio@wlqHK)eH@b%604-|x#}61Va`cGwG~WN4!Wo^OJS?qPpVah}>`CRnmhH1lGzv%` zJU%D@$3u$uS68sC^qW2|B{7X(WBezi#MIQ0FrbXY5$TD;lhe}^Q-e9lRKEz_3Xp(C zIB&`z*;cYC3JxW&v9d4q8zsBg6zfT?|9F(_RJz_P&p%l{T(+bvcvvPztMyJ#Q{=X^ zdz5@Ht5{E9SZP>Faauzt&72fM_!U@@(H0r3BEd1`bfr+VU{$pSq zNOS%N+|-l-{ss8Vl$oB35T=%Ca>wHO&Rdu!Z_`yMV%=;Rfi(1#>_qcN%a)Z(@SC@A zw2Xg#w^(PYF(rKh8$=SxzjVfly)_KQY$We||?*}=I+|SEpXt>_8JcZnsKhATuv+O5VPECv- z7@sgK(LXI6x5Mf3DY-f=t!g=r8s3mUrq1Ooz4Ou>ExXG!{(C@fyI6YAp<8m>ye6)e zy(C)yql{(P4Y@9@og%wYJx7S(!VTG*JY6k4slpF(jl3Ma<)3BA_L6K(b`xdyypfmW z&N981A(zctTHP|#%7)EhpfMpnF%fTiIM{j6l2qA7ICcS~xMLSo*A;h#j%@;@Id&;f zVdN|YDiUl9o+ zt9KtQ*H(f{k=i1`#YPP-MS#9k?WpX9ZnQa}7_3N$DOO)R#0Y0Eg3(@tkRnySl%FEk zuuy<8iW^h&;vWhfhF#G5x5LUo*ZScxm`YYg-1}kL;S*DK)u8 zn({9iV0CHzS|-~%mY((&+UL1p{BIrLuhVP(g&|*mZGzL_7TCP1Yrd4G>CKZ`4s0<~ qw3shwVU23haR28`qWj!$a6!Nx05)Nrg!om*(o3p;h$h#uT=PFoMGk@h delta 65183 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 4.13.0 < 5" + "web3": ">= 4.13.1 < 5" }, "devDependencies": { "@celo/dev-utils": "^0.0.5", @@ -37,13 +37,16 @@ "eslint-plugin-jest": "^28.6.0", "typescript": "^5.5.4", "typescript-eslint": "^7.17.0", - "web3": "^4.13.0" + "web3": "4.13.1-dev.cc99825.0" }, "dependencies": { "@celo/abis": "^11.0.0", "@celo/abis-l2": "npm:@celo/abis@12.0.0-canary.23", - "web3-eth-accounts": "^4.2.1", - "web3-utils": "^4.3.1" + "web3-eth-accounts": "4.2.2-dev.cc99825.0", + "web3-utils": "4.3.2-dev.cc99825.0" + }, + "resolutions": { + "web3-eth": "4.9.1-dev.cc99825.0" }, "patchedDependencies": { "@celo/dev-utils@0.0.5": "patches/@celo%2Fdev-utils@0.0.5.patch" diff --git a/src/cip64.ts b/src/cip64.ts index 1de8929..be7ce65 100644 --- a/src/cip64.ts +++ b/src/cip64.ts @@ -17,7 +17,6 @@ import { toUint8Array, txUtils, uint8ArrayToBigInt, - unpadUint8Array, } from "web3-eth-accounts"; import { bytesToHex, diff --git a/src/index.ts b/src/index.ts index de10c52..3555410 100644 --- a/src/index.ts +++ b/src/index.ts @@ -31,8 +31,9 @@ export class CeloTransactionTypesPlugin extends Web3PluginBase { public constructor() { super(); + console.log(); TransactionFactory.registerTransactionType( - CeloTransactionTypesPlugin.TX_TYPE, + `0x${CeloTransactionTypesPlugin.TX_TYPE.toString(16)}`, CIP64Transaction ); } @@ -176,7 +177,9 @@ class CeloTxMiddleware implements TransactionMiddleware { public async processTransaction( transaction: TransactionMiddlewareData ): Promise { - const { feeCurrency, gasPrice } = transaction; + const { feeCurrency, gasPrice } = + transaction as TransactionMiddlewareData & { feeCurrency?: HexString }; + if (!feeCurrency) { return transaction; } @@ -198,6 +201,7 @@ class CeloTxMiddleware implements TransactionMiddleware { // NOTE: small hack: // `transactionBuilder` calls this.ctx.transactionBuilder if defined this.ctx.transactionBuilder = undefined; + // @ts-expect-error const tx: CeloTransaction = await transactionBuilder({ ...options, transaction: transaction, diff --git a/src/tests/__snapshots__/index.test.ts.snap b/src/tests/__snapshots__/index.test.ts.snap index 538c8c3..2f089f8 100644 --- a/src/tests/__snapshots__/index.test.ts.snap +++ b/src/tests/__snapshots__/index.test.ts.snap @@ -20,7 +20,7 @@ CeloTransactionTypesPlugin { "_emitter": EventEmitter { "_events": {}, "_eventsCount": 0, - "maxListeners": 9007199254740991, + "maxListeners": 100, }, "_requestManager": Web3RequestManager { "_emitter": EventEmitter { @@ -84,6 +84,173 @@ CeloTransactionTypesPlugin { "config": { "blockHeaderTimeout": 10, "contractDataInputFill": "data", + "customTransactionSchema": { + "properties": { + "accessList": { + "items": { + "properties": { + "address": { + "format": "address", + }, + "storageKeys": { + "items": { + "format": "bytes32", + }, + "type": "array", + }, + }, + "type": "object", + }, + "type": "array", + }, + "chain": { + "enum": [ + "goerli", + "kovan", + "mainnet", + "rinkeby", + "ropsten", + "sepolia", + ], + "type": "string", + }, + "chainId": { + "format": "uint", + }, + "common": { + "properties": { + "baseChain": { + "enum": [ + "goerli", + "kovan", + "mainnet", + "rinkeby", + "ropsten", + "sepolia", + ], + "type": "string", + }, + "customChain": { + "properties": { + "chainId": { + "format": "uint", + }, + "name": { + "format": "string", + }, + "networkId": { + "format": "uint", + }, + }, + "type": "object", + }, + "hardfork": { + "enum": [ + "arrowGlacier", + "berlin", + "byzantium", + "chainstart", + "constantinople", + "dao", + "homestead", + "istanbul", + "london", + "merge", + "muirGlacier", + "petersburg", + "shanghai", + "spuriousDragon", + "tangerineWhistle", + ], + "type": "string", + }, + }, + "type": "object", + }, + "data": { + "format": "bytes", + }, + "effectiveGasPrice": { + "format": "uint", + }, + "feeCurrency": { + "format": "address", + }, + "from": { + "format": "address", + }, + "gas": { + "format": "uint", + }, + "gasLimit": { + "format": "uint", + }, + "gasPrice": { + "format": "uint", + }, + "hardfork": { + "enum": [ + "arrowGlacier", + "berlin", + "byzantium", + "chainstart", + "constantinople", + "dao", + "homestead", + "istanbul", + "london", + "merge", + "muirGlacier", + "petersburg", + "shanghai", + "spuriousDragon", + "tangerineWhistle", + ], + "type": "string", + }, + "input": { + "format": "bytes", + }, + "maxFeePerGas": { + "format": "uint", + }, + "maxPriorityFeePerGas": { + "format": "uint", + }, + "networkId": { + "format": "uint", + }, + "nonce": { + "format": "uint", + }, + "r": { + "format": "bytes32", + }, + "s": { + "format": "bytes32", + }, + "to": { + "oneOf": [ + { + "format": "address", + }, + { + "type": "null", + }, + ], + }, + "type": { + "format": "uint", + }, + "v": { + "format": "uint", + }, + "value": { + "format": "uint", + }, + }, + "type": "object", + }, "defaultAccount": undefined, "defaultBlock": "latest", "defaultChain": "mainnet", @@ -103,7 +270,7 @@ CeloTransactionTypesPlugin { "handleRevert": false, "maxListenersWarningThreshold": 100, "transactionBlockTimeout": 50, - "transactionBuilder": undefined, + "transactionBuilder": [Function: AsyncFunction], "transactionConfirmationBlocks": 24, "transactionConfirmationPollingInterval": undefined, "transactionPollingInterval": 1000, From 9f747aa93b1b62ea5088792a950d5e9d0b719577 Mon Sep 17 00:00:00 2001 From: Nicolas Brugneaux Date: Wed, 2 Oct 2024 10:57:19 +0200 Subject: [PATCH 5/9] chore: add release workflow --- .changeset/README.md | 8 +++++ .changeset/config.json | 19 ++++++++++++ .changeset/silver-mayflies-wonder.md | 5 ++++ .github/workflows/release.yml | 45 ++++++++++++++++++++++++++++ 4 files changed, 77 insertions(+) create mode 100644 .changeset/README.md create mode 100644 .changeset/config.json create mode 100644 .changeset/silver-mayflies-wonder.md create mode 100644 .github/workflows/release.yml diff --git a/.changeset/README.md b/.changeset/README.md new file mode 100644 index 0000000..e5b6d8d --- /dev/null +++ b/.changeset/README.md @@ -0,0 +1,8 @@ +# Changesets + +Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works +with multi-package repos, or single-package repos to help you version and publish your code. You can +find the full documentation for it [in our repository](https://github.com/changesets/changesets) + +We have a quick list of common questions to get you started engaging with this project in +[our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md) diff --git a/.changeset/config.json b/.changeset/config.json new file mode 100644 index 0000000..6d5eb08 --- /dev/null +++ b/.changeset/config.json @@ -0,0 +1,19 @@ +{ + "$schema": "https://unpkg.com/@changesets/config@3.0.2/schema.json", + "changelog": [ + "@changesets/changelog-github", + { "repo": "celo-org/web3-plugin-transaction-types" } + ], + + "commit": false, + "fixed": [], + "linked": [], + "access": "public", + "baseBranch": "main", + "updateInternalDependencies": "patch", + "ignore": [], + "snapshot": { + "useCalculatedVersion": true, + "prereleaseTemplate": "{tag}-{commit}" + } +} diff --git a/.changeset/silver-mayflies-wonder.md b/.changeset/silver-mayflies-wonder.md new file mode 100644 index 0000000..a4ed7db --- /dev/null +++ b/.changeset/silver-mayflies-wonder.md @@ -0,0 +1,5 @@ +--- +"@celo/web3-plugin-transaction-types": patch +--- + +Initial release diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..33a8971 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,45 @@ +name: Release Packages + +on: + push: + branches: + - main + - master + - "prerelease/*" + +concurrency: ${{ github.workflow }}-${{ github.ref }} + +jobs: + release: + name: Prepare or Publish + runs-on: ["self-hosted", "org", "npm-publish"] + permissions: + contents: write + id-token: write + pull-requests: write + repository-projects: write + steps: + - uses: actions/checkout@v4 + - uses: foundry-rs/foundry-toolchain@v1 + - uses: oven-sh/setup-bun@v2 + + - uses: docker://us-west1-docker.pkg.dev/devopsre/akeyless-public/akeyless-action:latest + with: + api-url: https://api.gateway.akeyless.celo-networks-dev.org + access-id: p-kf9vjzruht6l + static-secrets: '{"/static-secrets/NPM/npm-publish-token":"NPM_TOKEN"}' + + - run: bun install + - run: rm -rf node_modules/@celo/dev-utils/node_modules + + - uses: changesets/action@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + NPM_TOKEN: ${{ env.NPM_TOKEN }} + with: + # This expects you to have a script called release which does a build for your packages and calls changeset publish + publish: bun run prepublishOnly + version: | + bun x changeset version && + bun install && + rm -rf node_modules/@celo/dev-utils/node_modules From 33691e5d250982fbf2e3d4325e37341f4090cb3f Mon Sep 17 00:00:00 2001 From: Nicolas Brugneaux Date: Wed, 2 Oct 2024 10:58:48 +0200 Subject: [PATCH 6/9] chore: add tsbuildinfo to gitignore --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 8b97f33..7016d60 100644 --- a/.gitignore +++ b/.gitignore @@ -2,5 +2,5 @@ !.eslintrc.js !jest.config.js lib -*.tsbuildinfo.env +*.tsbuildinfo* .env \ No newline at end of file From 5a0a7412e89f5a7834cbcdfa28793786befaacf4 Mon Sep 17 00:00:00 2001 From: Nicolas Brugneaux Date: Wed, 2 Oct 2024 11:04:37 +0200 Subject: [PATCH 7/9] fix: wait for tests --- src/tests/utils.test.ts | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/src/tests/utils.test.ts b/src/tests/utils.test.ts index 56f2f9c..7f4679c 100644 --- a/src/tests/utils.test.ts +++ b/src/tests/utils.test.ts @@ -32,20 +32,20 @@ testWithAnvilL1("l1", (web3) => { describe("getContractAddressFromRegistry()", () => { test("returns a contract address", async () => { expect( - getContractAddressFromRegistry(plugin, "FeeCurrencyWhitelist") - ).resolves.toMatch(/^0x[0-9a-f]{40}$/i); + await getContractAddressFromRegistry(plugin, "FeeCurrencyWhitelist") + ).toMatch(/^0x[0-9a-f]{40}$/i); }); }); - describe("isCel2()", () => { - expect(isCel2(plugin)).resolves.toBe(false); + describe("isCel2()", async () => { + expect(await isCel2(plugin)).toBe(false); }); - test("isWhitelisted()", () => { - expect(isWhitelisted(plugin, "0x123")).resolves.toBe(false); + test("isWhitelisted()", async () => { + expect(await isWhitelisted(plugin, "0x123")).toBe(false); expect( - isWhitelisted(plugin, "0xc47bde654fEDA0d1dF4880f8BF00a5c650738586") - ).resolves.toBe(true); + await isWhitelisted(plugin, "0xc47bde654fEDA0d1dF4880f8BF00a5c650738586") + ).toBe(true); }); }); @@ -56,8 +56,8 @@ testWithAnvilL2("l2", (web3) => { describe("getContractAddressFromRegistry()", () => { test("returns a contract address", async () => { expect( - getContractAddressFromRegistry(plugin, "FeeCurrencyDirectory") - ).resolves.toMatch(/^0x[0-9a-f]{40}$/i); + await getContractAddressFromRegistry(plugin, "FeeCurrencyDirectory") + ).toMatch(/^0x[0-9a-f]{40}$/i); }); test("returns a non zero contract address", async () => { const address = await getContractAddressFromRegistry( @@ -67,22 +67,22 @@ testWithAnvilL2("l2", (web3) => { expect(address).toMatch(/^0x[0-9a-f]{40}$/i); expect(BigInt(address)).not.toEqual(0n); }); - test("throws if doesn't exists", async () => { + test("throws if doesn't exists", () => { expect( getContractAddressFromRegistry(plugin, "FAKE CONTRACT NAME") ).rejects.toMatchSnapshot(); }); }); - describe("isCel2()", () => { - expect(isCel2(plugin)).resolves.toBe(true); + describe("isCel2()", async () => { + expect(await isCel2(plugin)).toBe(true); }); - test("isWhitelisted", () => { + test("isWhitelisted", async () => { web3.setProvider(CeloChains.dango.rpcUrl); - expect(isWhitelisted(plugin, "0x123")).resolves.toBe(false); + expect(await isWhitelisted(plugin, "0x123")).toBe(false); expect( - isWhitelisted(plugin, "0x4822e58de6f5e485eF90df51C41CE01721331dC0") - ).resolves.toBe(true); + await isWhitelisted(plugin, "0x4822e58de6f5e485eF90df51C41CE01721331dC0") + ).toBe(true); }); }); From c13041e1c9a2999b65b96f4dc11e16b0938f40de Mon Sep 17 00:00:00 2001 From: Nicolas Brugneaux Date: Wed, 2 Oct 2024 11:08:24 +0200 Subject: [PATCH 8/9] test: console.log key first 5 chars --- .github/workflows/ci.yml | 3 +++ src/tests/e2e.test.ts | 17 +++++------------ 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 17b3201..9fb412c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -17,3 +17,6 @@ jobs: - run: rm -rf node_modules/@celo/dev-utils/node_modules - run: bun run build - run: bun run test + env: + TEST_ACCOUNT_1: ${{ secrets.TEST_ACCOUNT_1 }} + TEST_ACCOUNT_2: ${{ secrets.TEST_ACCOUNT_2 }} diff --git a/src/tests/e2e.test.ts b/src/tests/e2e.test.ts index 5b8978a..2c8d1b4 100644 --- a/src/tests/e2e.test.ts +++ b/src/tests/e2e.test.ts @@ -1,29 +1,22 @@ -import { testWithAnvilL1 } from "@celo/dev-utils/lib/anvil-test"; import { beforeAll, expect, test } from "bun:test"; import { CeloContract, CeloTransactionTypesPlugin } from ".."; -import Web3, { - Address, - Contract, - DataFormat, - FMT_BYTES, - FMT_NUMBER, -} from "web3"; +import Web3, { Address } from "web3"; import { stableTokenEurABI } from "@celo/abis"; -import { hexToBytes, toWei } from "web3-utils"; -import { CeloChains, TxTypeToPrefix } from "../utils"; -import { waitForTransactionReceipt } from "web3-eth"; -import { CIP64Transaction } from "../cip64"; +import { CeloChains } from "../utils"; let stable: CeloContract; let stableAddress: Address; const web3 = new Web3(CeloChains.alfajores.rpcUrl); +console.log(process.env.TEST_ACCOUNT_1!.slice(5)); +console.log(process.env.TEST_ACCOUNT_2!.slice(5)); const account = web3.eth.accounts.privateKeyToAccount( process.env.TEST_ACCOUNT_1 as string ); const account2 = web3.eth.accounts.privateKeyToAccount( process.env.TEST_ACCOUNT_2 as string ); + web3.eth.accounts.wallet?.add(account); beforeAll(async () => { From b2f01d205380200aa63a56a7470f1ab27fa167d0 Mon Sep 17 00:00:00 2001 From: Nicolas Brugneaux Date: Wed, 2 Oct 2024 11:22:15 +0200 Subject: [PATCH 9/9] test: fixing async tests --- src/tests/e2e.test.ts | 28 +++++++++++++++++++++++----- src/tests/utils.test.ts | 36 ++++++++++++++---------------------- 2 files changed, 37 insertions(+), 27 deletions(-) diff --git a/src/tests/e2e.test.ts b/src/tests/e2e.test.ts index 2c8d1b4..7d7835f 100644 --- a/src/tests/e2e.test.ts +++ b/src/tests/e2e.test.ts @@ -1,22 +1,26 @@ -import { beforeAll, expect, test } from "bun:test"; +import { + afterEach, + beforeAll, + beforeEach, + describe, + expect, + test, +} from "bun:test"; import { CeloContract, CeloTransactionTypesPlugin } from ".."; import Web3, { Address } from "web3"; import { stableTokenEurABI } from "@celo/abis"; -import { CeloChains } from "../utils"; +import { CeloChains, isWhitelisted } from "../utils"; let stable: CeloContract; let stableAddress: Address; const web3 = new Web3(CeloChains.alfajores.rpcUrl); -console.log(process.env.TEST_ACCOUNT_1!.slice(5)); -console.log(process.env.TEST_ACCOUNT_2!.slice(5)); const account = web3.eth.accounts.privateKeyToAccount( process.env.TEST_ACCOUNT_1 as string ); const account2 = web3.eth.accounts.privateKeyToAccount( process.env.TEST_ACCOUNT_2 as string ); - web3.eth.accounts.wallet?.add(account); beforeAll(async () => { @@ -97,3 +101,17 @@ test( }, { timeout: 10_000 } ); + +describe("dango", () => { + const _web3 = new Web3(CeloChains.dango.rpcUrl); + _web3.registerPlugin(new CeloTransactionTypesPlugin()); + + test("isWhitelisted", () => { + expect(_web3.celo.isValidFeeCurrency("0x123")).resolves.toBe(false); + expect( + _web3.celo.isValidFeeCurrency( + "0x4822e58de6f5e485eF90df51C41CE01721331dC0" + ) + ).resolves.toBe(true); + }); +}); diff --git a/src/tests/utils.test.ts b/src/tests/utils.test.ts index 7f4679c..b40a480 100644 --- a/src/tests/utils.test.ts +++ b/src/tests/utils.test.ts @@ -30,22 +30,22 @@ testWithAnvilL1("l1", (web3) => { web3.registerPlugin(plugin); describe("getContractAddressFromRegistry()", () => { - test("returns a contract address", async () => { + test("returns a contract address", () => { expect( - await getContractAddressFromRegistry(plugin, "FeeCurrencyWhitelist") - ).toMatch(/^0x[0-9a-f]{40}$/i); + getContractAddressFromRegistry(plugin, "FeeCurrencyWhitelist") + ).resolves.toMatch(/^0x[0-9a-f]{40}$/i); }); }); - describe("isCel2()", async () => { - expect(await isCel2(plugin)).toBe(false); + describe("isCel2()", () => { + expect(isCel2(plugin)).resolves.toBe(false); }); - test("isWhitelisted()", async () => { - expect(await isWhitelisted(plugin, "0x123")).toBe(false); + test("isWhitelisted()", () => { + expect(isWhitelisted(plugin, "0x123")).resolves.toBe(false); expect( - await isWhitelisted(plugin, "0xc47bde654fEDA0d1dF4880f8BF00a5c650738586") - ).toBe(true); + isWhitelisted(plugin, "0xc47bde654fEDA0d1dF4880f8BF00a5c650738586") + ).resolves.toBe(true); }); }); @@ -54,10 +54,10 @@ testWithAnvilL2("l2", (web3) => { web3.registerPlugin(plugin); describe("getContractAddressFromRegistry()", () => { - test("returns a contract address", async () => { + test("returns a contract address", () => { expect( - await getContractAddressFromRegistry(plugin, "FeeCurrencyDirectory") - ).toMatch(/^0x[0-9a-f]{40}$/i); + getContractAddressFromRegistry(plugin, "FeeCurrencyDirectory") + ).resolves.toMatch(/^0x[0-9a-f]{40}$/i); }); test("returns a non zero contract address", async () => { const address = await getContractAddressFromRegistry( @@ -74,15 +74,7 @@ testWithAnvilL2("l2", (web3) => { }); }); - describe("isCel2()", async () => { - expect(await isCel2(plugin)).toBe(true); - }); - - test("isWhitelisted", async () => { - web3.setProvider(CeloChains.dango.rpcUrl); - expect(await isWhitelisted(plugin, "0x123")).toBe(false); - expect( - await isWhitelisted(plugin, "0x4822e58de6f5e485eF90df51C41CE01721331dC0") - ).toBe(true); + describe("isCel2()", () => { + expect(isCel2(plugin)).resolves.toBe(true); }); });